I was wondering how I could update a filter on a CollectionViewSource with a ComboBox.
I have the following code:
<CollectionViewSource x:Key="cvsCars"
Source="{Binding Source={StaticResource odpCars}}">
<ComboBox Name="cbxMake" Margin="5" IsEnabled="False" />
I'm sure I need some sort of a SelectionChanged event for the ComboBox but I can't figure out a way to make it work with this code.
private void MakeFilterOn(object sender, RoutedEventArgs e)
{
cbxMake.IsEnabled = true;
cvsCars.Filter += new FilterEventHandler(cvsCars_Filter);
}
void cvsCars_Filter(object sender, FilterEventArgs e)
{
Car car = e.Item as Car;
if (car != null)
{
if (car.Maker.ToString() == cbxMake.SelectedItem.ToString())
{
e.Accepted = true;
}
else
{
e.Accepted = false;
}
}
}
Any advice is greatly appreciated.
The CollectionViewSource is populated by an ObjectDataProvider. The updates will be applied to a ListBox. MakeFilterOn is a CheckBox.
You'll have to refresh your CollectionViewSource's View...so, in your handler for your combobox's SelectionChanged event, refresh your cvs:
cvsCars.View.Refresh();
You may want to look into the databinding powers of WPF and then later, the Model View ViewModel (MVVM) "pattern". That way, you can bind the combobox's SelectedItem to a property on your window's DataContext and eliminate the need for handling the SelectionChanged event.
Related
I am trying to add new item in to Combobox .For ex : if the ComboBox itemssource having "one","two",and "three ". I am able to type by setting IsEditable property to true . New item "Four" which is need to save in combobox . Please share regarding this .
<Window.Resources>
<local:OrderInfoRepositiory x:Key="ordercollection"/>
</Window.Resources>
<ComboBox x:Name="combo" IsEditable="True" ItemsSource="{Binding ComboItems,Source={StaticResource ordercollection}}" Height="50" Width="150"/>
code behind :
void combo_PreviewKeyDown(object sender, KeyEventArgs e)
{
var combo=(sender as ComboBox);
(combo.DataContext as OrderInfoRepositiory).ComboItems.Add(combo.Text);
}
private ObservableCollection<string> comboItems = new ObservableCollection<string>();
public ObservableCollection<string> ComboItems
{
get { return comboItems; }
set
{
comboItems = value;
RaisePropertyChanged("ComboItems");
}
}
public OrderInfoRepositiory()
{
orderCollection = new ObservableCollection<OrderInfo>();
OrderInfoCollection = GenerateOrders();
foreach (OrderInfo o in orderCollection)
{
comboItems.Add(o.Country);
}
}
PreviewKeyDown
Your ComboBox is not bound to the EventHandler comboBox_PreviewKeyDown.
Are you really want to use PreviewKeyDown?
With PreviewKeyDown comboBox.Text still has the Text before excluding your pressed key. Use KeyDown instead.
Each Keypress will add the new and the old typed letters.
Typing "Hello World" will end in H, He, Hel, Hell, etc.
Check for Key.Return to add the Item on completion or use a button. Then you can still use the PreviewKeyDown Event.
void combo_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
var combo = (sender as ComboBox);
(combo.DataContext as OrderInfoRepository).ComboItems.Add(combo.Text);
}
}
DataContext
You are casting DataContext to OrderInfoRepositiory but there is no assignment in your code.
Add to your ComboBox:
DataContext="{Binding Source={StaticResource ordercollection}}"
Then you can change your ItemsSource:
ItemsSource="{Binding ComboItems}"
I prefer setting OrderInfoRepositiory in my underlying ViewModel, then you do not need the StaticResource and just bind to the property.
<ComboBox x:Name="combo" IsEditable="True" DataContext="{Binding Source={StaticResource ordercollection}}" ItemsSource="{Binding ComboItems}" Height="50" Width="150" KeyDown="combo_PreviewKeyDown"/>
Simple question over here.
Pretty simple code too.
I have a checkbox and I also have a combobox.
Basically the combobox's selected item should change whenever the the checkbox is ticked or unticked.That's not going so well right now.
It works when it's going from uncheked to checked, but when I uncheck it, the combobox value stays the same.
Checkbox Code:
private void linked_Checked(object sender, RoutedEventArgs e)
{
if (linked.IsChecked == true)
{
Chained.SelectedIndex = 0;
}
if (linked.IsChecked == false)
{
Chained.SelectedIndex = 1;
}
}
Combobox Code:
<ComboBox x:Name="Chained" Text="{Binding Chained, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="128,69,132,-92" Grid.Row="15" Visibility="Visible" SelectionChanged="Chained_SelectionChanged" >
<ComboBoxItem Content="True"/>
<ComboBoxItem Content="False"/>
</ComboBox>
This should be pretty straight forward right? So where am I going wrong?
If there's a way to do this in xaml then I'm all ears too.
Put it inside Unchecked event,
private void linked_UnChecked(object sender, RoutedEventArgs e)
{
if (linked.IsChecked == false)
{
Chained.SelectedIndex = 1;
}
}
The reason is when the checked event is fired, the state is not changed yet and this happends before the new value get set. It means when the event is fired you are still getting the old value. So I always find CheckStateChanged event much better . Because this event is fired when the check state is changes. so then you can say something like this.
private void checkBox1_CheckStateChanged(object sender, EventArgs e)
{
if (linked.CheckState == CheckState.Checked){
Chained.SelectedIndex = 0;
}
}
I have a ListPicker in an application page, but the SelectionChanged event gets called multiple times as the page loads. To avoid this, I have been following a previous question I asked here ListPicker SelectionChanged Event Called Multiple Times During Navigation in which the suggestion was instead of making ThemeListPicker_SelectionChanged make a parent stackpanel inside the datatemplate..', create a tap event in the StackPanel called stk_Tap, and 'use this tap stk_Tap to do your action as, this event would also get called every time the selection changed gets called but, it wont exhibit the buggy behavior like that of selection changed event'
Now I have adjusted my solution accordingly, but I do not know how to determine which item of the ListPicker is being selected or is currently selected. Also I removed the ListPicker SelectionChanged event in the ListPicker because I thought the StackPanel could get the item, but I am not sure if this is correct or how to do this?
XAML
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Name="PickerItemTemplate">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<toolkit:ListPicker x:Name="ThemeListPicker" Header="Theme"
ItemTemplate="{StaticResource PickerItemTemplate}"
SelectionChanged="ThemeListPicker_SelectionChanged"/>
XAML.CS
private void ThemeListPicker_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
if(ThemeListPicker.SelectedIndex != -1)
{
var theme = (sender as ListPicker).SelectedItem;
if (index == 0)
{
Settings.LightTheme.Value = true;
MessageBox.Show("light");
}
else
{
Settings.LightTheme.Value = false;
MessageBox.Show("dark");
}
}
}
*EDIT: How I updated my solution
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Name="PickerItemTemplate">
<StackPanel tap="stk_Tap">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<toolkit:ListPicker x:Name="ThemeListPicker" Header="Theme"
ItemTemplate="{StaticResource PickerItemTemplate}"
/>
So, even when I left the ListPicker SelectionChanged event in the code behind after making the modifications, I did not see the event being called twice upon the page loading/navigating to, but I am not sure how to get the currently selected item now?
EDIT2**
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
themeList = new List<TestApp.Common.Theme>();
themeList.Add(new TestApp.Common.Theme() { Name = "Darker", name = "dark" });
themeList.Add(new TestApp.Common.Theme() { Name = "Lighter", name = "light" });
ThemeListPicker.ItemsSource = themeList;
}
private void stk_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if (ThemeListPicker.SelectedIndex != -1)
{
//Need to get the current ThemeListPicker's 'name'
var selectedItem1 = (sender as StackPanel).DataContext as ListPicker;
//use selectedItem1
}
}
No need to extra tap event for such kind of work.
private void ThemeListPicker_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
if(ThemeListPicker.SelectedIndex==-1)
return;
var theme = (sender as ListPicker).SelectedItem;
if (index == 0)
{
Settings.LightTheme.Value = true;
MessageBox.Show("light");
}
else
{
Settings.LightTheme.Value = false;
MessageBox.Show("dark");
}
ThemeListPicker.SelectedIndex=-1
}
ListPicker SelectionChanged Event Called Multiple Times During Navigation
for above problem if i guess right you set listpicker's itemssource on OnNavigatedTo event. so modify you r onNavigatedTo method with
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.NavigationMode != NavigationMode.Back)
{
// Your code goes here
}
}
//Stack panel tap event
private void stack_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var selectedIrem = (Cast as your type)(sender as StackPanel).DataContext;
}
I have a longlistselector like the below image. now I wanna get the text of the item user's tapped. I've searched a lot but no solution found ;(
pay attention to the image please to give a sample code
http://amiryari.persiangig.com/image/stackoverflow-question.jpg
1) Wire up the SelectionChanged event on the LongListSelector control:
<phone:LongListSelector ItemsSource="{Binding MyListItems}"
SelectionChanged="LongListSelector_SelectionChanged">
2) Retrieve the selected item from the AddedItems collection in the SelectionChangedEventArgs:
private void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
var item = e.AddedItems[0];
}
}
3) If your item is an object, and the text is displayed through a property, then you would have access to the text through the property on your object:
MyListItemObject item = e.AddedItems[0] as MyListItemObject;
MessageBox.Show(item.FullName);
If your list is bound to a list of strings, then it would simply be the first item in the AddedItems collection:
string fullName = e.AddedItems[0].ToString();
MessageBox.Show(fullName);
You can always listen for the SelectionChanged event and obtain the string. There is another way if you are using a DataTemplate to style your items in the list. Declare Tapped event in DataTemplate like this:
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ContactImage}"/>
<TextBlock x:Name="NameTextBlock" Text="{Binding ContactName}" Tapped="NameTextBlock_Tapped"/>
</StackPanel>
</DataTemplate/>
Now in our code:
private void LongListSelector_SelectionChanged(object sender, BlahBlah e)
{
var tb = sender as Textblock;
string cName = tb.Text; //This is the string you wanted.
MessageBox.Show(cName);
}
I have a TabControl in WPF. I want to find an event that occurs when changing tabs. What is the name of this event?
The TabControl inherits from a Selector which contains the SelectionChanged event.
<TabControl SelectionChanged="OnSelectionChanged" ... />
private void OnSelectionChanged(Object sender, SelectionChangedEventArgs args)
{
var tc = sender as TabControl; //The sender is a type of TabControl...
if (tc != null)
{
var item = tc.SelectedItem;
//Do Stuff ...
}
}
I just want to add my point here. And I will use cool answer of #pratap k to do it.
<TabControl x:Name="MyTab" SelectionChanged="TabControl_SelectionChanged">
<TabItem x:Name="MyTabItem1" Header="One"/>
<TabItem x:Name="MyTabItem2" Header="2"/>
<TabItem x:Name="MyTabItem3" Header="Three"/>
</TabControl>
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (MyTabItem1 !=null && MyTabItem1.IsSelected)
// do your staff
if (MyTabItem2 !=null && MyTabItem2.IsSelected)
// do your staff
if (MyTabItem3 !=null && MyTabItem3.IsSelected)
// do your staff
}
As you see the difference is to add checking for NULL.
That is it!
I didn't get the selected answer to work, maybe something has changed, maybe my setup is different.
My solutions is straightforward, you cast the sender to become the tabControle. Then you pull out the selected TabItem (selectedValue) and cast this to an TabItem.
In my situation, I need to know "who" changed, so I look for the name of the TabItem, to better react to a specific event.
XAML
<TabControl SelectionChanged="OnTabItemChanged">
<TabItem Name="MainTap" Header="Dashboard"></TabItem
</TabControl>
C#
private async void OnTabItemChanged(object sender, SelectionChangedEventArgs e)
{
TabControl tabControl = sender as TabControl; // e.Source could have been used instead of sender as well
TabItem item = tabControl.SelectedValue as TabItem;
if (item.Name == "MainTap")
{
Debug.WriteLine(item.Name);
}
}