如何在MVVM(WPF)中处理多个复选框?

6
我是一名有用的助手,可以为您翻译文本。
我有一个扩展列表,每个扩展都有自己的复选框供用户选择: enter image description here 最终,我需要拥有所有已选择扩展的列表或ObservableCollection。
非MVVM方式实现这一点相当直接。我创建Checked或Unchecked事件,并添加发送者的内容。
视图:
<CheckBox Checked="ToggleButton_OnChecked" Unchecked="ToggleButton_OnUnchecked">exe</CheckBox>

代码后面:

    private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
    {
        var ext = ((CheckBox) sender).Content.ToString();
        Model.FirstRun.ExcludeExt.Add(ext);
    }

    private void ToggleButton_OnUnchecked(object sender, RoutedEventArgs e)
    {
        var ext = ((CheckBox)sender).Content.ToString();
        Model.FirstRun.ExcludeExt.Remove(ext);
    }

如果我想以MVVM风格实现这个,据我所知 - 我必须为每个复选框创建一个属性并将它们绑定到UI。这是很多工作。
有更简单的方法吗?

你觉得界面上有很多复选框是不是有点奇怪?要不要考虑使用带有复选框的组合框呢? - Sushil Mate
@SushilMate这会让在MVVM中实现绑定更容易吗? - Maverick Meerkat
顺便说一下,这只是最基本的用户界面,设计师稍后会进行改进。 - Maverick Meerkat
你应该首先创建一个模型。例如:class myCheckBox { bool Active; string Name; }class myCheckBoxList { List<myCheckBox >() ; ... Add(myCheckBox paramMyCheckBox ) { myCheckBox .Add (paramMyCheckBox ); } }之后,在视图上呈现模型*抱歉,我这里没有编译器来编写正确的代码。 - BruceOverflow
@DavidRefaeli 是的。无论是代码、设计、还是努力方面都是这样。 - Sushil Mate
1个回答

9

首先,您应该考虑结构,然后使用起来就不会那么费力,而且非常直观。

例如:您有一些扩展组。我会创建类似于以下伪代码的内容(例如,没有实现 INotifyPropertyChanged)。

public class ExtensionGroup
{
    public string Name {get; set;}
    public ObservableCollection<ExtensionInfo> ExtensionInfos {get; set;}
}

public class ExtensionInfo
{
    public string Extension {get; set;}
    public bool IsChecked {get; set;}

    public ExtensionInfo(string extension)
    {
        Extension = extension;
    }
}

在您的ViewModel中,您可以创建以下内容:
public ObservableCollection<ExtensionGroup> ExtensionGroups {get; set;}

现在您需要像这样添加数据。
var extensionGroup = new ExtensionGroup{Name = "Executables"};
extensionGroup.ExtensionInfos.Add(new ExtensionInfo("exe");
extensionGroup.ExtensionInfos.Add(new ExtensionInfo("bat");

接下来您将看到一个包含扩展名的所有组的列表。

您可以绑定此数据并完成操作。对于视图,您可以使用ListView与DataTemplate或其他项控件。

由于您只需要指定一次布局,因此代码量会减少,因此视图会变得更加容易。

/编辑 这是xaml的示例实现。我使用了ItemsControl而不是ListView。

<ItemsControl ItemsSource="{Binding ExtensionGroups}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Label Content="{Binding Name}"/>
                <ItemsControl ItemsSource="{Binding ExtensionInfos}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding IsChecked}"
                                      Content="{Binding Extension}"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

看起来像这样(只是加了两个带有两个分机的组)。 示例

然后你会如何进行绑定? - Maverick Meerkat
太棒了 - 我要试一下 :-) - Maverick Meerkat
运行得非常好。你只是忘记(在答案中)初始化(ExtensionGroups = new ObservableCollection<ExtensionGroup>(); var extensionGroup = new ExtensionGroup { Name = "Executables", ExtensionInfos = new ObservableCollection<ExtensionInfo>()};)并将extensionGroup添加到ExtensionGroups中(ExtensionGroups.Add(extensionGroup);)。 - Maverick Meerkat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接