【问题标题】:Selecting all CheckBoxes in ListBox not displayed properly选择列表框中的所有复选框未正确显示
【发布时间】:2015-02-21 15:08:22
【问题描述】:

如果我按下“全部选中”按钮,则应选择 ListBox 中的所有复选框并将其添加到存储所有选中项目的列表中。问题是只有可见的复选框才能正确更新。

这是我的 CheckBoxListItem 类:

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>

以及背后的代码:

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;
        }
    }

向下滚动后,左侧列表中的所有 20 个项目都可见,然后单击“检查所有”按钮效果很好,但我不知道为什么。

有人可以告诉我该实现有什么问题吗?选中/取消选中单个 CheckBox 有效,但 Check/Uncheck all 按钮无法正常工作。

【问题讨论】:

  • 这个问题+1。我可以重现这一点,我也搜索了一个没有成功的解决方案。在这种特殊情况下,最简单的解决方案可能是只处理 Check_All、Uncheck_All 中的 CheckedItems 的添加和删除,但问题的根本原因仍然未知。在stackoverflow.com/questions/16838954/… 显示类似的问题。

标签: c# wpf checkbox listbox


【解决方案1】:

来自 Blam 的评论(设置 VirtualizingStackPanel.VirtualizationMode="Standard" 几乎是解决方案。

添加VirtualizingStackPanel.IsVirtualizing="False":

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

这解决了问题(至少对我来说)

【讨论】:

  • 哇,谢谢!效果很好,从未听说过(甚至使用过)该属性。
猜你喜欢
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
  • 1970-01-01
相关资源
最近更新 更多