【问题标题】:How to two-way bind the ViewModel with CheckBoxes?如何将 ViewModel 与 CheckBox 双向绑定?
【发布时间】:2012-03-05 03:06:05
【问题描述】:

我有一个用户管理工具,可以编辑用户的权限。我让管理员在应用程序中选择复选框。

权限可能因服务器而异。现在我只有静态复选框,它真的很讨厌。

我试图弄清楚如何为复选框创建某种动态方案并跟踪它们何时被选中/取消选中。

当用户选择复选框时,我可以搜索对象并对数据库进行更改。

至少到目前为止我是这么想的。有没有人有任何意见或可能有这样的例子?

提前致谢!

【问题讨论】:

    标签: c# wpf mvvm checkbox


    【解决方案1】:

    只需使用ItemsControl,将其ItemsSource 绑定到代表权限的VM 集合。在ItemTemplate 中,您可以创建一个CheckBox,其IsChecked 绑定到您的项目VM 上的一个属性,该属性表示该权限的状态。

    然后您可以从源集合的对象中获取所有状态。

    【讨论】:

      【解决方案2】:

      假设有以下用户权限:

      [Flags]
      public enum UserPermissions
      {
          Administrator = 0x1,
          BackupOperator = 0x2,
          PowerUser = 0x4,
          User = 0x8,
          Guest = 0x10
      }
      

      枚举成员应该是数据绑定到复选框。

      好的,它将是 ListBoxCheckBox 项目:

      1) CheckBox 类具有布尔型 IsChecked 属性,但不能直接绑定到标志枚举。

      2) ListBox 类具有 ItemsSource 属性,可以绑定到集合。

      因此,有必要将标志枚举转换为标志视图模型列表:

      1) 创建代表 single 标志的 ViewModel。我们称它为UserPermissionViewModel 类。它应该具有 IsChecked 布尔值和 单个枚举标志值 Permission 属性。

      public class UserPermissionViewModel : ViewModelBase
      {
          public UserPermissionViewModel(UserPermissions permission, bool isSet)
          {
              Permission = permission;
              IsSet = isSet;
          }
      
          public UserPermissions Permission { get; private set; }
      
          public bool IsSet { get; set; }
      }
      

      2) 为所有标志创建 ViewModel(包含 UserPermissionViewModel 类的许多实例)。我们称它为UserPermissionsViewModel 类。此 ViewModel 应在构造函数中获取源枚举并将其转换为其标志表示的内部集合:UserPermissionViewModel 实例的集合。还应该有Result 属性,它将使用IsChecked 实例的IsChecked 属性值返回flags enum

      public class UserPermissionsViewModel
      {
          public UserPermissionsViewModel(UserPermissions permissions)
          {
              // Convert each flag of UserPermissions enum to UserPermissionViewModel and pass IsSet (true) if the permissions has the flag.
              Permissions = allPermissions.Select(singlePermission => new UserPermissionViewModel(singlePermission, permissions.HasFlag(singlePermission))).ToList();
          }
      
          public List<UserPermissionViewModel> Permissions
          {
              get;
              private set;
          }
      
          public UserPermissions Result
          {
              get
              {
                  // Iterate over Permissions list and get result flags enum.
              }
          }
      

      3) 在视图中创建ListBox,绑定到UserPermissionsViewModel类的权限列表属性。 ListBox 应该包含CheckBoxTextBlock 作为ItemTemplate。将它们相应地绑定到IsCheckedPermission 属性。

      之后,绑定应该起作用,结果可以使用Result属性获取。

      <ListBox ItemsSource="{Binding Path=PermissionsViewModel.Permissions}">
        <ListBox.ItemTemplate>
          <DataTemplate>
            <WrapPanel>
              <CheckBox IsChecked="{Binding Path=IsSet}" />
              <TextBlock VerticalAlignment="Center" Text="{Binding Path=Permission}" />
            </WrapPanel>
          </DataTemplate>
        </ListBox.ItemTemplate>
      </ListBox>
      

      【讨论】:

      • 我不建议使用ListBox,因为它引入了不需要的选择,普通的ItemsControl 应该这样做。
      【解决方案3】:

      我没有任何代码,但也许您可以使用一些变体:

      • 创建一组复选框并根据需要使它们可见/不可见。如果你只有一个最大值,最好。固定金额。

      • 创建一个复选框列表,动态创建它们并设置一个观察者(事件)来监听变化(IsChecked)。

      • 不要使用复选框,而是使用带有复选框的列表视图或列表框。

      【讨论】:

        【解决方案4】:

        H.B. 的一个例子。上面说:

            <ItemsControl ItemsSource="{Binding Privileges}">
                <ItemsControl .ItemTemplate>
                    <DataTemplate DataType="{x:Type Privilege}">
                        <StackPanel>
                            <TextBlock Text="{Binding Name}"/>
                            <CheckBox IsChecked="{Binding IsEnabled}"/>
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl .ItemTemplate>
            </ItemsControl >
        

        【讨论】:

        • 查看对 Serge 的回答的评论。
        猜你喜欢
        • 2019-03-05
        • 1970-01-01
        • 1970-01-01
        • 2017-11-17
        • 1970-01-01
        • 1970-01-01
        • 2021-12-01
        • 2019-11-13
        • 1970-01-01
        相关资源
        最近更新 更多