Как в C# проставить галочки всем элементам ListView?

Имеется ListView с чекбоксами размером, например, на 1000 элементов, нужно одним нажатием клавиши проставить все галочки. Гугль предлагает только обычный перебор и установку свойства checked в true для каждого элемента за раз. Это естественно занимает продолжительное время при большом количестве элементов.
  • Вопрос задан
  • 8113 просмотров
Решения вопроса 1
ZloyRabadaber
@ZloyRabadaber
Варианты есть разные, вот один из них.

Допустим у нас есть такой ListBox:

<ListBox ItemsSource="{Binding ItemCollection}">
    <ListBox.ItemTemplate>
        <DataTemplate>
             <StackPanel Orientation="Horizontal">
                 <CheckBox IsChecked="{Binding isChecked, Mode="TwoWay"}"/>
                 <TextBlock Text="{Binding Name}"/>
             </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>


Идея в том, чтобы каждому CheckBox`у добавить свойство и связать его с внешним (общим) CheckBox`ом. Вот что получилось

xaml разметка:

<Window x:Class="CheckBoxAll.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CheckBoxAll"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <ListBox x:Name="ListItems" ItemsSource="{Binding ItemCollection}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox IsChecked="{Binding isChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" local:CheckBoxExt.IsCheckExt="{Binding ElementName=CheckAll, Path=IsChecked}"/>
                            <TextBlock Text="{Binding Name}"/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <CheckBox x:Name="CheckAll" Content="Select all"/>
        </StackPanel>
    </Grid>
</Window>


Реализация расширенного свойства CheckBoxExt:

namespace CheckBoxAll
{
    public class CheckBoxExt
    {
        public static bool GetIsCheckExt(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsCheckExtProperty);
        }

        public static void SetIsCheckExt(DependencyObject obj, bool value)
        {
            obj.SetValue(IsCheckExtProperty, value);
        }

        // Using a DependencyProperty as the backing store for IsCheckExt.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsCheckExtProperty =
            DependencyProperty.RegisterAttached("IsCheckExt", typeof(bool), typeof(CheckBoxExt), new PropertyMetadata((dp,arg) =>
                {
                    if (dp is CheckBox)
                    {
                        var checkBox = dp as CheckBox;
                        checkBox.IsChecked = (bool)arg.NewValue;
                    }
                }));
    }
}


Вот и все. Могу выложить проект в студии, но не знаю как (краснею от стыда), могу выслать на мыло.
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
servitola
@servitola
вы можете попробовать класс VirtualizingStackPanel
Ответ написан
Комментировать
morello
@morello
Я думаю что по другому, как не перебором, не сделать. Если и найдется какой то класс, выполняющий подобную операцию — он, скорее всего, в своей основе будет иметь перебор.

Только что наваял пробный проект в в VS2008. Так у меня заполнение ListView на 1000 элементов визуально происходило дольше, нежели операция «Выбрать все».

Вот код, которым выбирал все элементы:
foreach (ListViewItem listItem in listView_Test.Items)
{
     listItem.Checked = true;
}

Так же и для снятия всех «выделений»:
foreach (ListViewItem listItem in listView_Test.Items)
{
     listItem.Checked = false;
}
Ответ написан
@PoliTeX
Может стоит уточнить? WPF или WinForms?
Ответ написан
@gleb_kudr
Посмотрите, можете ли вы применить виртуализацию. Чаще всего, готовые объекты на все элементы списка не нужны. Можно их хранить в каком-нибудь объекте с данными (например DataTable) и вызывать по мере необходимости.

Ну и кеширование, чтобы плавность прокрутки обеспечить.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы