MVVM, как реализовать флажок «Проверить все»

1

У меня есть несколько флажков, которые представляют столбцы, которые будут отображаться или скрываться в Datagrid. На данный момент все они работают, за исключением флажка "Проверить все". Когда выбрано, оно должно, как следует из названия, проверить все флажки внутри группы.

Ни один из этих флажков не привязан к модели просмотра, они влияют только на внешний вид данных в самом представлении. Одним из решений может быть реализация всех флажков в ViewModel, а затем выполнить команду "Проверить все" и установить для всех флагов значение true. Я просто не люблю эту идею, потому что я добавляю 20 свойств и различных команд и т.д. Все JUST поддерживают эту одно.

У меня были некоторые идеи, возможно, используя атрибут "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>
  • 1
    Так как все они на ваш взгляд, и не привязаны к вашей модели представления вообще. Вы бы справились со всем в представлении. флажок foreach, checkbox.isselected = true;
Теги:
xaml
wpf
checkbox
mvvm

2 ответа

3
Лучший ответ

Если вы не используете viewmodel, не можете ли вы сделать это в коде?

Прикрепите обработчик события к флажку check check check state state. Пока все элементы управления называются, они могут взаимодействовать с кодом позади.

  • 0
    Вы правы. Я снова думал строго с точки зрения XAML, так как был на виду. Все мои усилия были сосредоточены на магическом способе связывания их друг с другом через связывание, которое я забыл о коде View. Спасибо!
  • 0
    Не беспокойтесь - мы проводим так много времени, избегая кода позади в mvvm, это неудивительно :)
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 сетки 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 может просто перебирать коллекцию и выбирать все для выбора.

foreach(var item in this.Data)
{
    item.IsSelected = true;
}
  • 0
    Если бы нужна была модель представления, это был бы хороший подход. Однако я бы расширил его так, чтобы проверенное состояние флажка «проверить все» было привязано к значению в модели представления и использовалось для установки всех остальных. Таким образом, вы также можете отменить выбор.
  • 0
    ОП выразил предпочтение делать это без ВМ из-за чрезмерного назначения свойств, однако в заголовке сообщения говорится, что он хотел попробовать и сохранить его в MVVM. Этот подход решает обе проблемы. Очень мало присваивания свойств, и это сохраняет логику в вашей модели представления (которая удовлетворяет шаблону MVVM). Если ему не нужно проверять выбранное состояние объектов где-либо в приложении, и он используется только когда-либо связанным с View кодом, то да, модель представления - не тот подход, который нужно использовать. Использование свойства для переключения Select All вместо ICommand будет работать хорошо и уменьшит код еще больше. Спасибо за вклад.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню