WPF RadioButton 更改未更新 UI MVVM

标签 wpf mvvm

我有两个使用 MVVM 在 UI 中用作单选按钮列表的单选按钮。第一次加载用户控件时,选择了一个单选按钮,相关控件显示在 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>

下面是我的 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;
    }

最佳答案

单选按钮、组和绑定(bind)不能混用。令人惊讶的是,这是设计使然。

有三种方法可以在 UI 中更改绑定(bind)控件的值。一种是用户可以通过鼠标点击或按键自己完成。二是代码可以改变数据源的值,绑定(bind)会更新UI中的值。

第三种方法是在代码中显式设置值。如果这样做,您刚刚设置的控件上的绑定(bind)将被禁用。

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

但它会给单选按钮带来问题。因为分组的单选按钮会在代码中更改彼此的值。如果您在一个组中有三个单选按钮,并且其中一个被选中,则该单选按钮会找到该组中的其他按钮并取消选中它们。看看Reflector中的代码就知道了。

所以发生的事情正是您所观察到的:您单击单选按钮并禁用绑定(bind)。

这就是你要做的事情 - 这实际上很有意义。不要使用组。您可以使用单选按钮,但仅限于它们的视觉风格。忽略它们的分组功能。

相反,实现使绑定(bind)的 bool 属性在您的 View 模型中互斥的逻辑,例如:

public bool Option1
{
   set
   {
      _Option1 = value;
      if (value)
      {
         Option2 = false;
         Option3 = false;
      }
      OnPropertyChanged("Option1");
   }
}

如果你仔细想想,这个逻辑真的不应该出现在 View 中。因为它是逻辑,这就是 View 模型的用途。因此,虽然这有点痛苦,但你可以安慰自己,从架构上来说这是正确的做法。

关于WPF RadioButton 更改未更新 UI MVVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4773957/

相关文章:

c# - 如何加密ConnectionString中的sql用户名和密码?

wpf - 在 Vista/Windows 7 WPF FileDialog.Filter 中隐藏扩展

wpf - 使用 MVVM 模式时如何绑定(bind)到应用程序设置并能够编写单元测试?

c# - 将类对象绑定(bind)到 wpf 中的 ListView

wpf - ViewModel 可以与 MVVM 模式中的 View 对话吗?

WPF 绑定(bind) MVVM 中验证装饰器的可见性

wpf - "Content of a ContentControl must be a single element."异常

c# - 什么首先执行 : ToggleButton. IsChecked 绑定(bind)更新,或命令绑定(bind)?

c# - MvvmCross - 使用 Activity (上下文)参数实例化 ViewModel

wpf - 为什么 ListCollectionView.CustomSort 这么慢?