Как пометить/снять все флажки в списке?

237
31 марта 2018, 13:16

Есть список с CheckBox'ами, как по нажатию по кнопке пометить/снять пометку всех CheckBox'ов?

Answer 1

Вроде ничего сложного - привязки, команды...

Пусть у меня есть такая VM, представляющая один элемент списка:

class ItemVm : Vm
{
    string name;
    public string Name
    {
        get => name;
        set => Set(ref name, value, nameof(Name));
    }
    bool isChecked;
    public bool IsChecked
    {
        get => isChecked;
        set => Set(ref isChecked, value, nameof(IsChecked));
    }
}

А главная VM содержит коллекцию таких элементов и команды чтобы помечать или снимать пометки со всех элементов:

class MainVM : Vm
{
    public List<ItemVm> Items { get; }
    public ICommand CheckAllCommand { get; }
    public ICommand UncheckAllCommand { get; }
    public MainVM()
    {
        Items = new List<ItemVm>
        {
            new ItemVm { Name = "Молоко" },
            new ItemVm { Name = "Творог" },
            new ItemVm { Name = "Сметана" },
            new ItemVm { Name = "Кефир" },
            new ItemVm { Name = "Сыр" }
        };
        CheckAllCommand = new DelegateCommand(
            _ => Items.ForEach(item => item.IsChecked = true));
        UncheckAllCommand = new DelegateCommand(
            _ => Items.ForEach(item => item.IsChecked = false));
    }
}

Разметка:

<Grid Margin="5">
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ItemsControl ItemsSource="{Binding Items}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding Name}"
                          IsChecked="{Binding IsChecked}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    <UniformGrid Grid.Row="1" Rows="1" Margin="0,5,0,0">
        <Button Content="Check all" Margin="0,0,2.5,0"
                Command="{Binding CheckAllCommand}"/>
        <Button Content="Uncheck all" Margin="2.5,0,0,0"
                Command="{Binding UncheckAllCommand}"/>
    </UniformGrid>
</Grid>

Если вы хотите вместо двух кнопок использовать один CkeckBox, то можно обойтись одной командой, принимающей параметр:

CheckAllCommand = new DelegateCommand(
    o => Items.ForEach(item => item.IsChecked = (bool)o));

тогда в команду надо просто передать параметр - текущее состояние флажка:

<CheckBox Content="Check all"
          Command="{Binding CheckAllCommand}"
          CommandParameter="{Binding IsChecked,
              RelativeSource={RelativeSource Self}}"/>

Но я не стал делать этот вариант, т.к. вы не описали нужно ли как-то этому общему флажку реагировать на установку/снятие флажков в списке вручную по одному.

READ ALSO
Javascript new Regexp не находит совпадение

Javascript new Regexp не находит совпадение

Здравствуйте, допустим есть текст:

259
Проверка, есть ли бронирование

Проверка, есть ли бронирование

ЗдравствуйтеПишу приложение на nwjs для администрирования гостиницы

199
Как сделать несколько счётчиков кликов?

Как сделать несколько счётчиков кликов?

Через php клики по кнопке сохраняются в текстовый документ

302