MVVM如何实现“全部检查”复选框

时间:2014-08-25 17:17:35

标签: c# wpf xaml mvvm checkbox

我有许多复选框,表示将在Datagrid中显示或隐藏的列。截至目前,他们都工作,除了Check All Checkbox。选择后,顾名思义应该检查组中的所有复选框。

这些复选框都不与视图模型绑定,它们只会影响视图本身的数据外观。一种解决方案可能是实现ViewModel上的所有复选框,然后执行Check All命令并将所有标志设置为true。我只是不喜欢这个想法,因为我只是添加了20个属性和各种命令等,只是为了支持这一点。

我有一些想法可能使用" IsThreeState"属性但没有凝聚力。我也不反对在不同的容器中呈现它们,我不确定它是否有帮助。

<Expander  DockPanel.Dock="Top" Header="{x:Static p:Resources.shSettings}" IsExpanded="True">
            <DockPanel> 
                <GroupBox Header="Filter Columns" DockPanel.Dock="Right">
                    <ag:AutoGrid Columns="150, 150, 150" RowCount="7" RowHeight="20">
                        <CheckBox Content="Check All" />
                        <CheckBox Content="Co. Name" x:Name="filterCoName" />
                        <CheckBox Content="Rating" x:Name="filterRating" />

                        <CheckBox Content="Severity (!)" x:Name="filterSeverity" />
                        <CheckBox Content="Stn ID" x:Name="filterStation" />
                        <CheckBox Content="MB" x:Name="filterMB" />

                        <CheckBox Content="New" x:Name="filterNew" />
                        <CheckBox Content="KV" x:Name="filterKV" />
                        <CheckBox Content="STE Rating" x:Name="filterSiteRating" />

                        <CheckBox Content="QCA" x:Name="filterQCA" />
                        <CheckBox Content="Area" x:Name="filterArea" />
                        <CheckBox x:Name="filterDuration" Content="Duration" />

                        <CheckBox Content="Plan in Place" x:Name="filterPIP"  />
                        <CheckBox Content="Type" x:Name="filterType" />
                        <CheckBox Content="Rating(%)" x:Name="filterRatingPercent" />

                        <CheckBox Content="ID" x:Name="filterId" />
                        <CheckBox Content="Pre" x:Name="filterPre" />
                        <CheckBox Content="Deviation" x:Name="filterDeviation" />

                        <CheckBox Content="Status" x:Name="filterStatus" />
                        <CheckBox Content="Post" x:Name="filterPost" />
                        <CheckBox Content="Description" x:Name="filterDescription" />
                    </ag:AutoGrid>
                </GroupBox>
            </DockPanel>
        </Expander>

2 个答案:

答案 0 :(得分:3)

如果不使用viewmodel,你能否在后面的代码中执行此操作?

将事件处理程序附加到check all复选框选中状态更改事件。只要您的控件都已命名,就可以从后面的代码中进行交互。

答案 1 :(得分:1)

我知道这已经得到了解答,但我想分享一个你也可以使用的简单方法。您可以创建SelectedItem视图模型并在其中包装模型。然后在您的datacontext中,您可以触发一个ICommand,它迭代SelectedItems的集合并设置ISelected = true

/// <summary>
/// Provides a wrapper for objects that need to have their selected state checked.
/// </summary>
/// <typeparam name="T">The Type you are wrapping</typeparam>
public class SelectedItemViewModel<T> : ViewModel where T : class
{
    /// <summary>
    /// The item
    /// </summary>
    private readonly T item;

    /// <summary>
    /// The selected value of Item
    /// </summary>
    private bool isSelected;

    /// <summary>
    /// Initializes a new instance of the <see cref="SelectedItemViewModel{T}" /> class.
    /// </summary>
    /// <param name="item">The item.</param>
    /// <param name="eventService">The event service.</param>
    /// <param name="initialSelectedState">if set to <c>true</c> [initial selected state].</param>
    public SelectedItemViewModel(T item, bool initialSelectedState = false)
    {
        this.item = item;
        this.isSelected = initialSelectedState;
        this.eventService = eventService;
    }

    /// <summary>
    /// Gets the item.
    /// </summary>
    public T Item
    {
        get
        {
            return this.item;
        }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this instance is selected.
    /// </summary>
    public bool IsSelected
    {
        get
        {
            return this.isSelected;
        }

        set
        {
            this.isSelected = value;
            this.OnPropertyChanged();
        }
    }
}

如果您只是想严格显示内容而没有任何实际数据,那么在视图模型构造函数中将其设置为这样。

private List<selectedItem<string>> data;
public MainViewModel()
{
    this.data = new List<SelectedItem<string>>
    {
        new SelectedItem<string>("Co. Name");
        new SelectedItem<string>("Rating");
        // Etc.
    }
}

public List<SelectedItem<string>> Data
{
    get { return this.data; }
    set { this.data = value; this.OnPropertyChanged(); }
}

最后,在您的XAML中,您只需将数据网格的ItemSource属性绑定到您的集合,然后将复选框绑定到IsSelected属性。此示例使用DataGrid,因为我不知道您在所提供的代码段中使用了哪些数据网格。

<DataGrid ItemsSource="{Binding Path=Data}"
            DockPanel.Dock="Top"
            AutoGenerateColumns="False"
            HorizontalContentAlignment="Center"
            HorizontalAlignment="Stretch"
            MouseDoubleClick="DataGrid_DoubleClick"
            Margin="0 0 0 5">

    <DataGrid.Columns>
    <!-- Create a column per value. This can be automated by using a template instead. -->
        <DataGridTemplateColumn Header="{Binding Path=Item}">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding Path=IsSelected,UpdateSourceTrigger=PropertyChanged}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>

然后,您的ICommand实现可以迭代集合并将all设置为选中。

foreach(var item in this.Data)
{
    item.IsSelected = true;
}