Prevent SelectedItem in WPF ComboBox becoming null after edit to text - c#

I need the ComboBox below to keep the SelectedItem when I edit the text, at the moment as soon as I edit the text the SelectedItem turns null.
<ComboBox x:Name="FilterGroups"
IsEditable="True"
DisplayMemberPath="Code"
Text="{Binding FilterGroupCode}"
ItemsSource="{Binding FilterGroups}"
SelectedItem="{Binding SelectedFilterGroup}"
Margin="10,0"/>
My goal is to detect that the item has been edited, currently I have no idea which item was edited since the SelectedItem becomes null.
And a null SelectedItem to me at the moment means "New" item.

As AGH's Comment.
Xaml
<ComboBox x:Name="myFilterGroups"
ItemsSource="{Binding FilterGroups}"
DisplayMemberPath="Name"
SelectedItem="{Binding SelectedFilterGroup}"
IsEditable="True" Height="20"
LostFocus="myFilterGroups_LostFocus"
>
</ComboBox>
Code Behind
private void myFilterGroups_LostFocus(object sender, RoutedEventArgs e)
{
var selItem = myFilterGroups.SelectedItem;
if (selItem == null)
// Create New Item
;
}

Related

C# ComboBox SelectedItem not Updating

My problem is that after I select a item in the ComboBox, the first item or "default" item of the combobox stays empty but if I click the combobox the values beneath show up are selectable etc. but I want the clicked one to show in the "default/first" place.
What I tried so far
XAML:
<ComboBox Margin="55,0,0,10" Height="20" Width="145" VerticalAlignment="Center" HorizontalAlignment="Left"
ItemsSource="{Binding TabItems, Source={StaticResource MainWindowViewModelRefactored}, Mode=TwoWay}"
SelectedItem="{Binding SelectedItem, Source={StaticResource MainWindowViewModelRefactored}, Mode=TwoWay}"
DisplayMemberPath="Header">
</ComboBox>
Property:
public TabItem SelectedItem {
get {
return _selectedItem;
}
set {
UpdateTCVCollection(value);
_selectedItem = value;
NotifyPropertyChanged("SelectedItem");
}
}
If I open up the combobox the selecteditem is highlighted, but I also want it to be shown in the "first place" when the ComboBox is closed.
You can add a method when the index has changed, then remove the item that the user selected and add it at the begining.
I've set the value of Sorted to false because that way the value you selected won't be reorganized in your ComboBox.
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e) {
RadItem selectedItem = ComboBox1.SelectedItem as RadItem;
if (selectedItem != null) {
ComboBox1.Items.Remove(selectedItem);
ComboBox1.Items.Sorted = true;
ComboBox1.Items.Sorted = false;
ComboBox1.Items.Insert(0, selectedItem);
ComboBox1.Text = selectedItem.Text;
}
}
Add the UpdateSourceTrigger to your Combobox.
UpdateSourceTrigger=PropertyChanged
Example:
<ComboBox Margin="55,0,0,10" Height="20" Width="145" VerticalAlignment="Center" HorizontalAlignment="Left"
ItemsSource="{Binding TabItems, Source={StaticResource MainWindowViewModelRefactored}, Mode=TwoWay}"
SelectedItem="{Binding SelectedItem, Source={StaticResource MainWindowViewModelRefactored}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Header">
</ComboBox>
Have a look to this MSDN link
That should help you with your problem.
Greetings

How to change the ComboBox CHOOSE AN ITEM header after changing Language property

We are localizing our app and letting the user change the language dynamically while the app is running.
This is working well except for the ComboBox that lets them change the language.
Here is the XAML
<ComboBox
x:Name="label_Languages"
x:Uid="label_Languages"
Header="Preferred language"
ItemsSource="{Binding Languages}"
SelectedItem="{Binding LanguageSelected, Mode=TwoWay}"
PickerFlyoutBase.Title="{Binding Title, Mode=OneWay}"
SelectedValuePath="Name"
SelectionChanged="label_Languages_SelectionChanged" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding NativeName}" />
<TextBlock Text="{Binding EnglishName}" FontSize="14" Foreground="{ThemeResource TextBoxForegroundHeaderThemeBrush}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Here is the C#
private void label_Languages_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox languages = sender as ComboBox;
SettingsViewModel vm = DataContext as SettingsViewModel;
SettingsViewModel.Language language = label_Languages.SelectedItem as SettingsViewModel.Language;
if (language != null)
{
string locale = language.Name;
App.ChangeAppLanguage(locale);
page_SettingsPage.Language = App.CultureInfo.Name;
page_SettingsPage.FlowDirection = App.FlowDirection;
// Modify the language of each page UI element and render it in the new language.
label_Languages.Header = ResourceStrings.GetString("label_Languages.Header");
// update a bunch of other items that all work perfectly!
}
}
Here are the before and after screenshots showing how the CHOOSE AND ITEM doesn't change.
How do I get the ComboBox to change it header? Thanks for your interest in this.
[UPDATE]
Based on #Dev Dua's suggestion, I added PickerFlyoutBase.Title="{Binding Title, Mode=OneWay}" to the ComboBox XAML and added the Title property to the ViewModel. After the language is changed in the ViewModel, RaisePropertyChanged for the Title property causes the Title property to be retrieved later. Presumably by the PickerFlyoutBase.Title binding. Unfortunately, even though the correct value is returned by the Title property, the ComboBox continues to show the English CHOOSE AN ITEM regardless.
Here is the ViewModel:
public Language _LanguageSelected = null;
public Language LanguageSelected
{
get { return _LanguageSelected; }
set
{
_LanguageSelected = value;
App.ChangeAppLanguage(_LanguageSelected.Name);
RaisePropertyChanged("LanguageSelected");
RaisePropertyChanged("Title");
}
}
public string Title
{ get { return ResourceStrings.GetString("LanguageChooseAnItem.Title"); } }
Something appears broken in the ComboBox binding to the PickerFlyoutBase.Title property. Using a string constant in XAML works as expected.
Use the PickerFlyoutBase.Title property! Bind it to whatever text is to be displayed.
<ComboBox PlaceholderText="Something here" PickerFlyoutBase.Title="Edited">
<ComboBoxItem Content="A"/>
<ComboBoxItem Content="B"/>
<ComboBoxItem Content="C"/>
<ComboBoxItem Content="D"/>
<ComboBoxItem Content="A"/>
<ComboBoxItem Content="A"/>
</ComboBox>

Binding to a ListBox SelectedItem

I have a Window with ListBox on the left Side and TextBox on the right Side. The Textbox is binding to the Selected Item of the ListBox. The Textbox has a SaveContentCommand.
If you leave the Textbox with Enter or the Tab the SaveContentCommand is executed correct. But if i use the mouse to select something else the selecteditem is changed and then the SaveContentCommand is executed. This means the SaveContentCommand is used on another item.
I have tried to hack something like RenameLastSelectedItem()
But is there a correct/better way?
My List:
<customControls:MyListBox x:Name="UserListBox"
Grid.Row="1"
Grid.Column="0"
ItemsSource="{Binding Users}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Top"
Style="{DynamicResource MyListBoxStyle}"
ItemContainerStyle="{DynamicResource MyListBoxItemUserListStyle}">
My TextBox:
<customControls:MyTextBox x:Uid="textBoxName"
x:Name="textBoxNameOfSelectedItems"
Text="{Binding SelectedItem.Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=true, Mode=TwoWay}"
focus:FocusExtension.IsFocused="{Binding SelectedItem.IsNameFocused, Mode=TwoWay}"
focus:FocusExtension.EnableSelection="True"
UseKeyboardBinding="true"
Style="{DynamicResource MyTextBoxStyle}"
SaveContentCommand="{Binding SelectedItem.UpdateCommand}"
In the set method of the SelectedItem, save the previous item. This code will run when the selected item is changed when selecting a new item with the mouse..
SelectedItem
{get { return _selectedItem;}
set
{
//null check
SaveContent(_selectedItem);
_selectedItem = value;
}
}

WPF ComboBox Master - Slave

I have 2 combobox master-slave in this way:
<ComboBox ItemSource="{Binding MySource}" SelectedItem="{Binding MySelectedItem}" DisplayMemberPath="Description" />
<ComboBox ItemSource="{Binding MySelectedItem.Items}" IsSynchronizedWithCurrentItem="{x:Null}" />
But when I select one item of first combobox which it has empty list of Items after I have selected one of them with Items and selected item in second combobox. The text in second combobox is not empty. I have tried with IsSynchronizedWithCurrentItem="False" too.
What is the problem?
I am not sur to understand what you are trying to say... But I am pretty sur that you didn't notify a PropertyChanged after modify your "MySelectedItem" and you forget the mode=TwoWay...
If you want to use the SelectedItem in your ViewModel:
Xaml:
<ComboBox ItemSource="{Binding MySource}" SelectedItem="{Binding MySelectedItem, mode=TwoWay}" DisplayMemberPath="Description" />
<ComboBox ItemSource="{Binding MySelectedItem.Items}"/>
ViewModel:
private YourItemType _mySelectedItem;
public YourItemType MySelectedItem
{
get { return (_mySelectedItem);}
set
{
if (_mySelectedItem != value)
{
_mySelectedItem = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("MySelectedItem"));
}
}
}
If you just want to do a filtering:
<ComboBox ItemSource="{Binding MySource}" DisplayMemberPath="Description" name="source"/>
<ComboBox ItemSource="{Binding SelectedItem.Items, ElementName=source}"/>
I have found the problem, it was that I have associated a command with interactivity in the combobox and this was catching an exception and didn't continue with the execution.

detect selecteditem details in ListBox from MVVM app in windows phone

I have the following view.xaml and I bind a collection(SavedTracksCollection from viewmodel) to this list box and it displays the items in UI.
<phone:PanoramaItem Name="MusicTracks" Header="Saved Tracks" >
<Grid>
<ListBox x:Name="list" ItemsSource="{Binding SavedTracksCollection}" SelectedItem="{Binding SelectedItemTrack,Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Background="Red" >
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding TrackTitle}"/>
<TextBlock Text="{Binding TrackUri}"/>
</StackPanel>
</Button>
<DataTemplate>
</ListBox.ItemTemplate>
</Grid>
</phone:PanoramaItem>
And the i have the following property defined in my viewmodel(this viewmodel is set as data context for my view) for the selecteditem binding "SelectedItemTrack".And i am binding SavedTracksCollection to the itemsource of the list.
private SavedTracksModel _SelectedItemTrack;
public SavedTracksModel SelectedItemTrack
{
get {
return _SelectedItemTrack;
}
set
{
if (value!=null)
_SelectedItemTrack = value;
//RaisePropertyChanged("SelectedItemTrack"); I dont think we need this.Let me know otherwise.
}
}
private List<SavedTracksModel> _SavedTracksCollection = new List<SavedTracksModel>();
public List<SavedTracksModel> SavedTracksCollection
{
get
{
return GetSavedTracks();
}
set
{
this._SavedTracksCollection = value;
RaisePropertyChanged("SavedTracksCollection");
}
}
But i am not able to determine how do i capture the SelectedITem event when user selectes an item from the Listbox .Currently it doesn't trigger the set method of the SelectedITemTrack .Once i capture the event with the details of selected item binding "TrackUri" i want to go to a new page where i can play the track.
any idea how to fix the issue ?
The first solution I can think of, why not just use the SelectionChanged event on ListBox?
<ListBox x:Name="list" ItemsSource="{Binding SavedTracksCollection}"
SelectedItem="{Binding SelectedItemTrack,Mode=TwoWay}"
SelectionChanged="List_OnSelectionChanged"/>
// in code behind
private void List_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// navigate here after validating the selected item
// or raise Command in your ViewModel programatically
}

Categories

Resources