ComboBox in WPF/MVVM with null and empty string - c#

I have a problem with my ComboBox in WPF/MVVM project. After changing ViewModel (I use everything correctly: INotifyPropertyChanged, ObservableCollection, etc.) the ComboBox is not always changes its value. I've debugged it and the getter from ViewModel returned the correct value (string.Empty), but the ComboBox displayed a value from the list. A bit of code below:
// It doesn't work.
<ComboBox ItemsSource="{Binding ItemsCollection}" SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
// It works.
<TextBlock Text="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
TextBlock is updated correctly if SelectedItem is string.Empty or null, but ComboBox is not updated correctly (old value stays) if SelectedItem is string.Empty. It's cleared only if SelectedItem is null value.
Why is this occurring?
// EDIT:
Maybe I explained it wrong. I have two grids: on the left I have tree with files and on the right I have properties of selected file. When I first select file A, which doesn't have setted property, the ComboBox is empty. If I choose file B, which have this property setted, it appers in the ComboBox. Next if I select file C with empty property, the old value stays in ComboBox (from before selected file - B). If this property from C is null, not string.Empty, ComboBox is cleared.

Use CollectionViewSource instead of ObservableCollection for ComboBox.

Related

Combobox SelectedItem is not retrieved properly

I have saved all combobox values which are added dynmaically to a collection.
No i want to retrieve the info. When I retrieve it my combobox values are not displayed in it.
We use Telerik component here
<tele:RadComboBox HorizontalAlignment="Stretch" DisplayMemberPath="content" ItemsSource="{Binding ManyValue,Mode=TwoWay}" SelectedItem="{Binding MyValue, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}">
ManyValue is a dropdown of values which has id,content
Myvalue is selected value what I have selected in combobox
ManyValue is a collection of viewmodel to combobox.
MyValue is a property of ViewModel i.e. selected item of comboobox.
This is happening correctly when I select, But when I retrieve the data,In collection Items are present but something wrong in Binding so that am not able to display it.
I do the save properly. But when I retrieve unable to load the already selected item in combobox.
Can anyone help?
Set the SelectedItem,SelectedValue and SelectedValuePath did the trick for me

WPF - Editable combobox text overwritten by source on load

I have an editable combobox that also has an item source which is effectively used to prompt users with some standard entries for that box whilst giving them the freedom to enter custom entries if they wish. So, everything works fine accept when I bind to a property with a value (which is not one off the list) it sets the comboboxes text to the first item in the item source. Just to be clear, the following steps demonstrate the issue.
I open the View with a clean Model (all the properties are null/default values
I enter a custom value into the editable combobox
I save the Model
I close the View
I re-open the View with the previously saved Model
The custom value which I saved should be displayed in the editable combobox, however it is overwritten by the first value in the item source list
Note: The value in the Model property is not changed, this issue is purely visual.
So, how can I stop the itemsource overwriting custom entries?
Here is the combo box XAML:
<ComboBox IsEditable="True" ItemsSource="{Binding Contact_Types, Mode=OneTime, Source={StaticResource Resources}}" Text="{Binding Model.type, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />

Two-way binding combobox to enum

I have a View that is linked to my ViewModel using a DataTemplate, like this
<DataTemplate DataType="{x:Type ViewModels:ViewModel}">
<Views:View />
</DataTemplate>
The ViewModel holds a property ProcessOption that is of type MyEnum?, where MyEnum is a custom enumeration that has let's say 3 values: Single, Multiple and All. I am trying to bind a combobox to this property, so the approach I am following is:
ViewModel has a property of List<string> that is
public List<string> Options
{
get
{
return Enum.GetNames(typeof(MyEnum)).ToList();
}
}
to which I bind the ItemsSource property of the Combobox. Then, in addition to the ProcessOption property, the ViewModel also has an OptionName property (of string), which is intended to hold the selected option's name. The ViewModel implements INotifyPropertyChanged and both properties raise the PropertyChanged event in their setters. The binding I am using then is:
<ComboBox ItemsSource="{Binding Options}"
SelectedItem="{Binding OptionName}"
SelectedValue="{Binding ProcessOption}"/>
This works fine up to this point. Initially the combobox is empty and both properties are null, and when the user selects an option this is propagated to the ViewModel as it should.
The problem appears when I load the data from a Database, and I want to load the controls with initial values. In this case, in the ViewModel's constructor I have this:
this.ProcessOption = objectFromDB.ProcessOption // this is the value restored from DB, let's say it is MyEnum.Multiple
this.OptionName = Options.First(x => x.Equals(Enum.GetName(typeof(MyEnum), objectFromDB.ProcessOption)));
The problem is, although the above sets the two properties to their correct values, they are later set to null from the Combobox binding, so the initial values are not kept. I have also tried to do something like if (value == null) { return; } in the properties' setters, in which case they have the correct values after the View loads, however the Combobox still does not display the correct option, it is empty.
I should also note that I've also tried setting IsSynchronisedWithCurrentItem and it doesn't make any difference, apart from the fact that the first element is displayed instead of the combobox being empty.
Can anyone help with this binding? Any help will be very much appreciated, this is driving me crazy!
<ComboBox ItemsSource="{Binding Options}"
SelectedItem="{Binding OptionName}"
SelectedValue="{Binding ProcessOption}"/>
Your binding doesn't look like it should work at all -- you don't have TwoWay binding set up, and I think SelectedItem and SelectedValue is an either/or proposition.
I suggest that you get rid of OptionName and just bind SelectedItem to ProcessOption (TwoWay) with an IValueConverter that will convert to/from string.

Changing Data Context for Data Template clears Combo Box selection

I have a TreeView that permits the user to select different items. The display for each item is determined using Data Templates with the DataType set to the appropriate ViewModel type. The DataContext is automatically set based on the selected item in the tree view to the appropriate ViewModel.
Here's the problem:
One of the DataTemplates has a ComboBox bound to an ObservableCollection to get the list of items and a property to get/set the SelectedValue in the ViewModel.
When I select one item of this type, and then select another item of the same type, the ComboBox displays blank instead of the correct selected item. It appears that the Combo Box is setting the SelectedValue property to NULL immediately after the transition to the new item, and then never updating.
<ComboBox Margin="1,0"
ItemsSource="{Binding ItemsToSelect}"
SelectedValue="{Binding SelectedValue}"
SelectedValuePath="ValuePath" DisplayMemberPath="DisplayPath"
IsEnabled="{Binding CanSelectItem}">
</ComboBox>
The really strange part is if I select an item of a different type between selecting items of the same type, it always displays correctly.
I've tried ignoring the NULL value in the SelectedValue setter, and that didn't work regardless of whether I also raised the PropertyChanged event or not.
private MyObject selectedValue;
public MyObject SelectedValue
{
get
{
return selectedValue;
}
set
{
if (value != null)
{
this.selectedValue = value;
}
this.OnPropertyChanged("SelectedValue");
}
}
Looking at the similar questions while writing this lead me to an interesting attribute that I hadn't found yet - IsSynchronizedWithCurrentItem from this question. At first, I thought this solved the problem, but alas it just changes the behavior somewhat.
With this attribute set to True, the combo doesn't entirely clear its selection, but instead just marks the first item as selected. So, instead of being set to NULL, now the SelectedValue property is being set to the first item in the list.
Anyone have any ideas for a solution?
If I understand your problem correctly, a couple of things are going on here.
First you do not have Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} set in your bindings.
Second, the property binding will only update if there is a change in the value itself.
Check this out Data Binding
I figured out a work around, but it isn't quite what I wanted.
I changed the binding to use SelectedItem instead of SelectedValue, and the issue doesn't occur.
I got the idea from this question.
So I changed
SelectedValue="{Binding SelectedValue}"
To (and renamed my ViewModel Property):
SelectedItem="{Binding SelectedItem}"
After updating the uses of this property in the ViewModel, everything worked.

Combobox DataBinding

I'm having a problem with a combobox. I use databinding to display the content of a list (guinodes). My UINode items in the list implement INotifyPropertyChanged and raise PropertyChanged on name changes. If I change the name of an item the combobox is updated, however combobox.Text remains the old value. Also please note that combobox.SelectedValue.ToString() contains only the type.
Databinding looks like that :
ItemsSource="{Binding ElementName=graphCanvas, Path=guinodes}"
your combobox SelectedValue or SelectedItem should be the selected UINode item, just take it and get the information you want from it. dont know why you use combobox.Text?
use this:
<ComboBox x:Name="SubCategory" ItemsSource="{Binding ElementName=graphCanvas, Path=guinodes}" DisplayMemberPath="SubCategoryName" SelectedValuePath="**SubCategoryID**" SelectedValue="{Binding SubCategoryID,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />
Good Luck

Categories

Resources