Reputation: 307
I have a combo box defined as such
<ComboBox Name="RoomDropDown" Visibility="{Binding Path=RoomDropDownVisible,Mode=OneWay,Converter={StaticResource BoolVisibilityConvertor}}"
ItemsSource="{Binding Path=RoomList,Mode=OneWay}" DisplayMemberPath="display" SelectedValuePath="display" SelectedValue="{Binding Path=Room,Mode=TwoWay}"/>
There are 2 properties defined in the ViewModel, RoomList which is List and the Room property which is a string.
First time when i run the app everything works fine, and the Drop Down gets the correct values as well as the correct values is selected. However on a certain conditions the RoomList property is changed to a different source & the Room property is also changed. The problem that is now happening is the Combo Box is showing the correct values but the selected value is not getting selected. Worse, we can live with that, but the setter is also not firing when the value is manually changed in the DropDown.
Any pointers on what is going wrong here?
Followup: Don't think I managed to get the exact problem across, here is some sample code that I wanted to add to illustrate the problem:
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel VerticalAlignment="Center" Width="100">
<ComboBox Name="TestBox" Height="20" Width="100" ItemsSource="{Binding Path=ComboSource}" DisplayMemberPath="display" SelectedValuePath="code"
SelectedValue="{Binding Path=ComboSelection,Mode=TwoWay}"/>
<Button Content="Click Here" Click="Button_Click" />
</StackPanel>
</Grid>
public MainPage()
{
InitializeComponent();
this.Loaded += (s, e) =>
{
var temp = new List<Binding>();
temp.Add(new Binding() { code = "1", display = "One" });
temp.Add(new Binding() { code = "2", display = "Two" });
this.ComboSource = temp;
this.ComboSelection = "1";
this.DataContext = this;
};
}
private static readonly DependencyProperty ComboSelectionProperty =
DependencyProperty.Register("ComboSelectionProperty", typeof(string), typeof(MainPage), new PropertyMetadata(null));
public string ComboSelection
{
get { return (string)GetValue(ComboSelectionProperty); }
set
{
SetValue(ComboSelectionProperty, value);
this.RaisePropertyChanged("ComboSelection");
}
}
private static readonly DependencyProperty ComboSourceProperty =
DependencyProperty.Register("ComboSourceProperty", typeof(List<Binding>), typeof(MainPage), new PropertyMetadata(null));
public List<Binding> ComboSource
{
get
{
return (List<Binding>)GetValue(ComboSourceProperty);
}
set
{
SetValue(ComboSourceProperty, value);
this.RaisePropertyChanged("ComboSource");
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var temp = new List<Binding>();
temp.Add(new Binding() { code = "3", display = "Three" });
temp.Add(new Binding() { code = "4", display = "Four" });
this.ComboSource = temp;
this.ComboSelection = "3";
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
public class Binding
{
public string code {get; set;}
public string display { get; set; }
}
Not strictly MVVM, but to explain the problem, when the button click event is fired, the Combosource is changed with a new selection being made, however that selection does not bind and the problem i mentioned above starts happening.
Upvotes: 2
Views: 1830
Reputation: 3175
There seems to be a bug in ComboBox data binding where the binding will completely break if the data it is binding to SelectedValue becomes null.
Place a breakpoint in the ComboSelection setter and see if it is ever getting set to null. If this is the source of the problem, add this to your setter:
public string ComboSelection
{
// .....
set
{
if(value == null)
return;
// .....
}
}
On a side note, you probably don't need use a dependency property to back ComboSelection. The data binding for this should work just fine on a normal property as long as you keep using PropertyChanged.
Upvotes: 0
Reputation: 292765
Your SelectedValuePath
is "display", which I assume is a string property of the Room
class. But you're binding SelectedValue
to the Room
property of your viewmodel, and I assume this property is of type Room
... So the SelectedValue
is of the type string, and you're binding it to a property of type Room
: it can't work because there is no conversion between those types.
Instead of using the SelectedValue
property, why not use the SelectedItem
?
<ComboBox Name="RoomDropDown" Visibility="{Binding Path=RoomDropDownVisible,Mode=OneWay,Converter={StaticResource BoolVisibilityConvertor}}"
ItemsSource="{Binding Path=RoomList,Mode=OneWay}" DisplayMemberPath="display" SelectedItem="{Binding Path=Room,Mode=TwoWay}"/>
Upvotes: 2