Reputation: 1084
I have a seemingly simple task, that is giving me headaches and would appreciate some help.
What I want to accomplish is binding two boolean values to the IsChecked property of two RadioButton
s, sharing the same GroupName
(so only one is checked at a time).
The problem I'm facing is that when the Content of a ContentPresenter is about to change (through binding to SelectedItem of a ComboBox), the current content receives a call to a Property-setter with a value of the same property but from the view model that is about to become the new content. (!) The end result is that there is a change of the view model despite no click on the RadioButton bound to the property in question.
I've put together a sample app that shows the problem. To reproduce, run the app and follow these steps:
If between #3 and #4, you first select "Two" in the combobox to have the ContentPresenter display another view (as selected through the DataTemplate), the problem does not appear!?
Could someone please explain why the property is set at step #4 when the views are exchanged by the ContentPresenter, and what can be done about it?
Upvotes: 5
Views: 405
Reputation: 132548
DataTemplates are cached, so both One
and Three
use the exact same UserControl
. You can verify this by adding a Loaded
event to the control and switching between options.
When you switch to Two
and back to Three
, WPf will simply re-draw the item from cache, however switching to One
and back to Three
, it changes the DataContext
behind the object. I think this is causing the problem because it seems to be clearing the 2nd RadioButton IsChecked prior to removing the DataContext, so the end result is that Property2 gets set to false. This does not happen if both One
and Three
have the 2nd radio button selected.
Usually in this kind of situation, I will have the VM contain an ObservableCollection<T> Items
and an int SelectedIndex
. I'll then draw the UI using a ListBox
which has been overwritten to use RadioButtons for the items. This way only one item can be selected at a time, and there is only one property for storing the selected item.
Upvotes: 1
Reputation: 2112
It seems to be a bug (the Content of the ContentPresenter changes, but the DataContext does not).
But I can offer you a solution. In your example do the following (MainWindow.xaml):
<StackPanel>
<ComboBox ItemsSource="{Binding MyItems, Mode=OneWay}" Name="cmbBox" DisplayMemberPath="ID" SelectionChanged="cmbBox_SelectionChanged"/>
<ContentPresenter Name="cp1" />
</StackPanel>
In the cmbBox_SelectionChanged looks the following:
private void cmbBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
cp1.Content = null;
cp1.DataContext = null;
cp1.Content = cmbBox.SelectedItem;
}
This solves the problem (not a great solution, but a workaround).
Upvotes: 0