RadioButton的绑定问题

时间:2012-03-01 13:06:20

标签: c# wpf data-binding

我有一个看似简单的任务,这让我很头疼,并会感激一些帮助。

我想要完成的是将两个布尔值绑定到两个RadioButton的IsChecked属性,共享相同的GroupName(因此一次只检查一个)。

我面临的问题是,当ContentPresenter的内容即将发生变化时(通过绑定到ComboBox的SelectedItem),当前内容会接收对Property-setter的调用,该属性具有相同属性但是从即将成为新内容的视图模型。 (!)最终结果是视图模型发生了变化,尽管没有点击与相关属性绑定的RadioButton。

我已将together a sample app用于显示问题。要重现,请运行该应用并按照以下步骤操作:

  1. 在组合框中选择“一个”=>检查MyPropery,MyProperty2不是。
  2. 在组合框中选择“三个”=>检查MyPropery,MyProperty2不是。
  3. 选择“三个”时,请点击MyProperty2 =>检查MyProperty2(也在调试输出窗口中指示)
  4. 在组合框中选择“一个”=>检查MyPropery,MyProperty2不是。 注意调试窗口如何显示对象“Three”的MyProperty2如何设置为false
  5. 在组合框中选择“三个”=>现在都没有检查Radiobuttons(由于#4)。
  6. 如果在#3和#4之间,首先在组合框中选择“Two”以使ContentPresenter显示另一个视图(通过DataTemplate选择),问题不会出现!?

    有人可以解释一下,当ContentPresenter交换视图时,为什么在第4步设置属性,以及可以采取哪些措施?

2 个答案:

答案 0 :(得分:1)

DataTemplates已缓存,因此OneThree都使用完全相同的UserControl。您可以通过向控件添加Loaded事件并在选项之间切换来验证这一点。

当您切换到Two并返回Three时,WPf只会从缓存中重新绘制该项,但切换到One并返回Three,它更改对象后面的DataContext。我认为这是导致问题的原因,因为它似乎在删除DataContext之前清除了第二个RadioButton IsChecked,因此最终结果是Property2被设置为false。如果OneThree都选择了第二个单选按钮,则不会发生这种情况。

通常在这种情况下,我会让VM包含ObservableCollection<T> Itemsint SelectedIndex。然后我将使用已被覆盖的ListBox绘制UI以使用RadioButtons作为项目。这样,一次只能选择一个项目,并且只有一个属性用于存储所选项目。

答案 1 :(得分:0)

这似乎是一个错误(ContentPresenter的内容发生了变化,但DataContext却没有。)

但我可以为您提供解决方案。在您的示例中,执行以下操作(MainWindow.xaml):

<StackPanel>
     <ComboBox ItemsSource="{Binding MyItems, Mode=OneWay}" Name="cmbBox" DisplayMemberPath="ID" SelectionChanged="cmbBox_SelectionChanged"/>
     <ContentPresenter Name="cp1" />
</StackPanel>

在cmbBox_SelectionChanged中查找以下内容:

private void cmbBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    cp1.Content = null;
    cp1.DataContext = null;
    cp1.Content = cmbBox.SelectedItem;
}

这解决了问题(不是一个很好的解决方案,而是一种解决方法)。