WPF RadioButton更改未更新UI MVVM

Ari*_*ant 3 wpf mvvm

我有两个单选按钮用作使用MVVM的UI中的radioButton List.当第一次加载用户控件时,选择一个单选按钮,并在UI中显示相关控件...现在,当我更改单选按钮时,UI不会更新.

以下是XAML示例:

<Label Grid.Column="0" Grid.Row="3" Content="Exchange Details:" Margin="3" VerticalContentAlignment="Center" Style="{StaticResource NormalLabelStyle}"></Label>
 <Grid Grid.Column="1" Grid.Row="3" Width="200">
  <Grid.ColumnDefinitions>
   <ColumnDefinition Width="Auto"/>
   <ColumnDefinition Width="20"/>
  <ColumnDefinition Width="Auto"/>
 </Grid.ColumnDefinitions>
<RadioButton GroupName="rdoExchange" Content="Basic" IsChecked="{Binding Path=ExchangeDetailsBasic}"  Grid.Column="0" VerticalContentAlignment="Center" VerticalAlignment="Center"></RadioButton>
<RadioButton GroupName="rdoExchange" Content="Advanced" IsChecked="{Binding Path=ExchangeDetailsAdvanced}" Grid.Column="2" VerticalContentAlignment="Center" VerticalAlignment="Center"></RadioButton
 </Grid> 

 <Label Grid.Column="3" Grid.Row="0" Content="Number of Mailbox Profiles:" VerticalContentAlignment="Center" Style="{StaticResource NormalLabelStyle}" Visibility="{Binding Path=IsAdvanced}" ></Label>
 <telerik:RadNumericUpDown Grid.Column="4" Grid.Row="0" Margin="3" Value="{Binding Path=NumberofMailboxProfiles}" IsInteger="True" Minimum="1" Maximum="4"  HorizontalAlignment="Left" Visibility="{Binding Path=IsAdvanced}">< /telerik:RadNumericUpDown>
Run Code Online (Sandbox Code Playgroud)

下面是我的ViewModel代码:

 private enum ExchangeDetails{
        Basic,
        Advanced
 }

 private bool isBasicMode = true;

 public bool ExchangeDetailsBasic {
         get {
            return this.isBasicMode;
        }

        set {
            if (value) {
                this.applicationSpecificRequirements[ExchangeDetailsKey] = ExchangeDetails.Basic.ToString();
                if (!this.isBasicMode) {
                    this.CheckBasicOrAdvancedSelecteAndDisplayView();
                }
            }
        }
    }

 public bool ExchangeDetailsAdvanced {
        get {
            return !this.isBasicMode;
        }

        set {
            if (value) {
                this.applicationSpecificRequirements[ExchangeDetailsKey] = ExchangeDetails.Advanced.ToString();
                this.CheckBasicOrAdvancedSelecteAndDisplayView();
            }
        }
    }

    public Visibility IsAdvanced { get; private set; }

    private void CheckBasicOrAdvancedSelecteAndDisplayView() {
        this.isBasicMode = this.applicationSpecificRequirements.ContainsKey(ExchangeDetailsKey) ? (this.applicationSpecificRequirements[ExchangeDetailsKey].Equals(ExchangeDetails.Basic.ToString()) ? true : false) : true;
        this.IsAdvanced = this.isBasicMode ? Visibility.Collapsed : Visibility.Visible;
    }
Run Code Online (Sandbox Code Playgroud)

Rob*_*ney 8

单选按钮,组和绑定不会混合.令人惊讶的是,这是设计上的.

有三种方法可以更改UI中绑定控件的值.一个是用户可以通过鼠标点击或按键自己完成.第二个是代码可以更改数据源的值,绑定将更新UI中的值.

第三种方法是在代码中明确设置值.如果这样做,则禁用您刚刚设置的控件上的绑定.

这有点违反直觉.您希望新值被推送到数据源.设计假设是,如果您希望在数据源中更改值,则需要在数据源中更改它,并且您的代码正在操作UI,因为您不希望它再被绑定.这为您提供了一种手动覆盖绑定的简单方法 - 只需在代码中设置控件的值 - 这不会强迫您查找Binding对象并显式操作它.这有一定的意义.我猜.

但它会产生单选按钮的问题.因为分组单选按钮会在代码中更改彼此的值.如果组中有三个单选按钮,并且一个单选按钮被检查,则单选按钮会找到组中的其他按钮并取消选中它们.如果查看Reflector中的代码,可以看到这个.

所以会发生什么正是你所观察到的:你点击单选按钮,绑定被禁用.

这就是你对它的所作所为 - 这实际上有相当大的意义.不要使用组.您可以使用单选按钮,但仅限于其视觉样式.忽略他们的分组功能.

相反,在视图模型中实现使绑定的布尔属性互斥的逻辑,例如:

public bool Option1
{
   set
   {
      _Option1 = value;
      if (value)
      {
         Option2 = false;
         Option3 = false;
      }
      OnPropertyChanged("Option1");
   }
}
Run Code Online (Sandbox Code Playgroud)

如果你考虑一下,无论如何这个逻辑真的不应该在视图中.因为它是逻辑,这就是视图模型的用途.因此,虽然这是一种痛苦,但你可以安慰自己,从结构上来说这是正确的事情.