baris1892
baris1892

Reputation: 1051

Selecting all CheckBoxes in ListBox not displayed properly

If I press a button "Check All" all CheckBoxes in a ListBox should be selected and added to a list where all checked items are stored. The problem is that only the visible checkboxes are updated properly.

Here is my CheckBoxListItem class:

public class Cbli : INotifyPropertyChanged
{
    private string _name;
    private Boolean _isChecked;

    public string Name
    {
        get { return _name; }
        set { _name = value; OnPropertyChanged("Name"); }
    }

    public bool IsChecked
    {
        get { return _isChecked; }
        set { _isChecked = value; OnPropertyChanged("IsChecked"); }
    }

    public override string ToString()
    {
        return string.Format("Name: {0}, IsChecked: {1}", _name, _isChecked);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML:

<Window x:Class="ListBoxBuggy.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:listBoxBuggy="clr-namespace:ListBoxBuggy"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding RelativeSource={RelativeSource Self}}" WindowStartupLocation="CenterScreen">

    <Window.Resources>
        <DataTemplate x:Key="CheckBoxListItemTemplateNew" DataType="listBoxBuggy:Cbli">
            <CheckBox Name="CheckBox"
                      IsChecked="{Binding IsChecked}"
                      Checked="Update"
                      Unchecked="Update"
                      FontSize="14">
                <TextBlock Text="{Binding Name}" FontSize="14"/>
            </CheckBox>
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <ListBox HorizontalAlignment="Left" Height="300" VerticalAlignment="Top" Width="168"
                 ItemsSource="{Binding MyItemList}"
                 ItemTemplate="{StaticResource CheckBoxListItemTemplateNew}" 
                 />
        <ListBox HorizontalAlignment="Left" Height="290" Margin="297,10,0,0" VerticalAlignment="Top" Width="195"
                 ItemsSource="{Binding CheckedItems}"
                 />
        <Button Content="Check All" HorizontalAlignment="Left" Margin="173,10,0,0" VerticalAlignment="Top" Width="75" Click="Check_All"/>
        <Button Content="Uncheck All" HorizontalAlignment="Left" Margin="173,52,0,0" VerticalAlignment="Top" Width="75" Click="Uncheck_All"/>
    </Grid>
</Window>

And the code behind:

public partial class MainWindow : Window
    {
        public ObservableCollection<Cbli> MyItemList { get; set; }
        public ObservableCollection<Cbli> CheckedItems { get; set; }

        public MainWindow()
        {
            // add dummy data
            MyItemList = new ObservableCollection<Cbli>();
            CheckedItems = new ObservableCollection<Cbli>();
            for (int i = 0; i < 20; i++)
            {
                Cbli cbli = new Cbli
                {
                    Name = "Test " + i,
                    IsChecked = i < 5 || i > 15
                };
                MyItemList.Add(cbli);

                if (cbli.IsChecked)
                    CheckedItems.Add(cbli);
            }

            InitializeComponent();
        }

        private void Update(object sender, RoutedEventArgs e)
        {
            CheckBox selectedCheckbox = (CheckBox)sender;
            Cbli cbli = (Cbli)selectedCheckbox.DataContext;

            if (cbli.IsChecked)
                CheckedItems.Add(cbli);
            else
                CheckedItems.Remove(cbli);
        }

        private void Check_All(object sender, RoutedEventArgs e)
        {
            foreach (Cbli cbli in MyItemList)
                cbli.IsChecked = true;
        }

        private void Uncheck_All(object sender, RoutedEventArgs e)
        {
            foreach (Cbli cbli in MyItemList)
                cbli.IsChecked = false;
        }
    }

After scrolling down, so all 20 items on the left list are visible and clicking then the "check all" button is working pretty well, but I don't know why.

Can someone please tell me what is wrong with that implementation? Checking/unchecking a single CheckBox is working, but the Check/Uncheck all buttons aren't working properly.

Upvotes: 2

Views: 1207

Answers (1)

Rainer Schaack
Rainer Schaack

Reputation: 1618

The comment from Blam (setting VirtualizingStackPanel.VirtualizationMode="Standard" was nearly the solution.

Add VirtualizingStackPanel.IsVirtualizing="False":

<ListBox HorizontalAlignment="Left" Height="300" VerticalAlignment="Top" Width="168"
         ItemsSource="{Binding MyItemList}"
         ItemTemplate="{StaticResource CheckBoxListItemTemplateNew}"
         VirtualizingStackPanel.IsVirtualizing="False" />

This solved the problem (at least for me)

Upvotes: 2

Related Questions