简体   繁体   English

如何将ViewModel与CheckBoxes双向绑定?

[英]How to two-way bind the ViewModel with CheckBoxes?

I have a user admin tool that edits permissions for users. 我有一个用户管理工具,可以为用户编辑权限。 I have the admin select checkboxes at the application. 我在应用程序中有管理员选择复选框。

The permissions can be different from server to server. 服务器之间的权限可能不同。 Right now I just have static checkboxes and its real nasty. 现在,我只有静态复选框及其真实的讨厌之处。

I'm trying to figure out how to create some kind of dynamic scheme for the checkboxes and track when they have been checked / unchecked. 我试图弄清楚如何为复选框创建某种动态方案并跟踪何时选中/取消选中它们。

When the user selects the checkboxes I could just search through the object and make the changes to the database. 当用户选中复选框时,我可以只搜索对象并对数据库进行更改。

Well at least that's the way I have thought of it so far. 至少到目前为止,这就是我一直认为的方式。 Does anyone have any input or maybe an example of something like this in action ? 有人在行动中提供任何输入或示例吗?

Thanks in Advance! 提前致谢!

Just use an ItemsControl , bind its ItemsSource to a collection of VMs which represent a permission. 只需使用ItemsControl ,将其ItemsSource绑定到代表权限的VM集合即可。 In the ItemTemplate you can create a CheckBox whose IsChecked is bound to a property on your item VM which represents the state of that permission. ItemTemplate您可以创建一个CheckBoxIsChecked绑定到项目VM上代表该权限状态的属性。

You then can get all the states from the source collection's objects. 然后,您可以从源集合的对象获取所有状态。

Let's assume there are the following user permissions: 假设有以下用户权限:

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

Enum members should be data bound to the checkboxes. 枚举成员应该是绑定到复选框的数据。

Okay, it will be ListBox with CheckBox items: 好的,它将是带有CheckBox项目的ListBox

1) CheckBox class has boolean IsChecked property, but it can't be bound directly to flags enumeration. 1) CheckBox类具有boolean IsChecked属性,但不能直接绑定到标志枚举。

2) ListBox class has ItemsSource property which can be bound to collection. 2) ListBox类具有可以绑定到集合的ItemsSource属性。

So, it is necessary to convert the flags enumeration to List of flag ViewModels: 因此,有必要将标志枚举转换为标志ViewModels的列表:

1) Create ViewModel which represents single flag. 1)创建代表单个标志的ViewModel。 Let's call it UserPermissionViewModel class. 我们称它为UserPermissionViewModel类。 It should have IsChecked boolean and the single enum flag value Permission properties. 它应该具有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) Create ViewModel for all flags (contains many instances of UserPermissionViewModel class). 2)为所有标志创建ViewModel(包含UserPermissionViewModel类的许多实例)。 Let's call it UserPermissionsViewModel class. 我们称它为UserPermissionsViewModel类。 This ViewModel should take the source enum in constructor and convert it to internal collection of its flags representation: collection of UserPermissionViewModel instances. 此ViewModel应该在构造函数中使用源枚举,并将其转换为其标志表示的内部集合: UserPermissionViewModel实例的集合。 Also there should be Result property which will return the flags enum using IsChecked property values of UserPermissionViewModel instances. 还应该有Result属性,该属性将使用UserPermissionViewModel实例的IsChecked属性值返回标志枚举

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) Create ListBox in the View, bind it to permission list property of UserPermissionsViewModel class. 3)在视图中创建ListBox ,将其绑定到UserPermissionsViewModel类的权限列表属性。 ListBox should contain CheckBox and TextBlock as ItemTemplate . ListBox应该包含CheckBoxTextBlock作为ItemTemplate Bind them to IsChecked and Permission properties accordingly. 相应地将它们绑定到IsCheckedPermission属性。

After that, the binding should work, the result can be taken using Result property. 之后,绑定应该起作用,可以使用Result属性获取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>

I don't have any code, but maybe some variations you could use: 我没有任何代码,但也许可以使用一些变体:

  • Create a set of check boxes and make them visible/invisible as you need them. 创建一组复选框,并根据需要使它们可见/不可见。 Preferably if you only have a max. 最好是如果您只有最大 fixed amount. 固定值。

  • Create a list of check boxes, create them dynamically and set an observer (event) to listen to changes (IsChecked). 创建复选框列表,动态创建它们,并设置观察者(事件)以侦听更改(IsChecked)。

  • Don't use checkboxes but a listview or listbox with checkboxes. 不要使用复选框,而是使用列表视图或带有复选框的列表框。

An example of what HB says above: HB上面说的一个例子:

    <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 >

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM