【问题标题】:WPF - Extend ListView with checkable AND selectable ListViewItemsWPF - 使用可检查和可选择的 ListViewItems 扩展 ListView
【发布时间】:2011-02-16 00:31:56
【问题描述】:

我已经阅读了很多关于使用 IsSelected 绑定的复选框扩展 ListViews 的示例。但我想要更多。

我想要在选中状态和选中状态之间分开,所以我得到一个列表框,它有一个选中的项目,但可以有多个选中的项目。 不幸的是,ListViewItem 没有用于检查的属性,我看不到让 ListView 与自定义 CheckableListViewItem 一起使用的可能性。

当然,我可以使用带有选中属性的对象列表作为 ItemSource,但我认为这不是一个好方法。检查与否是列表或项目容器的问题,而不是其中列出的对象。除此之外,我不希望我的所有类(如用户、角色、组)都有对应的对象,如 checkableUser、checkableRole 和 checkableGroup。

我想要的行为可以很容易地为 UI 完成

<DataTemplate x:Key="CheckBoxCell">
   <StackPanel Orientation="Horizontal">
      <CheckBox />
   </StackPanel>
</DataTemplate>

还有一个

<GridViewColumn CellTemplate="{StaticResource CheckBoxCell}" Width="30"/>

但是如果没有绑定复选框,我无法检查它是否被选中。

有没有办法完成类似的事情?对我来说完美的解决方案是拥有 listView1.SelectedItem、listView1.CheckedItems 和 listView1.UncheckedItems,当然还有 listView1.CheckItem 和 listView1.UncheckItem。

感谢您的帮助。

【问题讨论】:

    标签: wpf xaml listview checkbox


    【解决方案1】:

    好的,我明白了。 没什么可做的,但是因为我对整个 WPF 的东西都是新手,所以需要做一些工作来弄清楚。 这是解决方案:

    public class CheckableListViewItem : ListViewItem
    {
        [Category("Appearance")]
        [Bindable(true)]
        public bool IsChecked { get; set; }
    }
    
    public class CheckableListView : ListView
    {
        public IList CheckedItems
        {
            get
            {
                List<object> CheckedItems = new List<object>();
                for (int i=0;i < this.Items.Count; ++i)
                {
                    if ((this.ItemContainerGenerator.ContainerFromIndex(i) as CheckableListViewItem).IsChecked)
                        CheckedItems.Add(this.Items[i]);
                }
                return CheckedItems;
            }
        }
        public bool IsChecked(int index)
        {
            if (index < this.Items.Count) return (this.ItemContainerGenerator.ContainerFromIndex(index) as CheckableListViewItem).IsChecked;
            else throw new IndexOutOfRangeException();
        }
        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            if (item is CheckableListViewItem) return true;
            else return false;
        }
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new CheckableListViewItem();
        }
    }
    

    在 Window.Resources 下插入您的 XAML(clr = 我的类命名空间):

    <DataTemplate x:Key="CheckBoxCell">
        <StackPanel Orientation="Horizontal">
            <CheckBox IsChecked="{Binding Path=IsChecked, 
                RelativeSource={RelativeSource FindAncestor, 
                AncestorType={x:Type clr:CheckableListViewItem}}}" />
        </StackPanel>
    </DataTemplate>
    

    这就是你的 CheckableListView:

    <clr:CheckableListView SelectionMode="Single" [...] >
            <ListView.View>
                <GridView>
                    <GridViewColumn CellTemplate="{StaticResource CheckBoxCell}" 
                          Width="30"/>
                    [...]
                </GridView>
            </ListView.View>
        </clr:CheckableListView>
    

    也许这可以帮助遇到同样问题的人。

    【讨论】:

      【解决方案2】:

      为此,您必须创建自定义ListBox 和自定义ListBoxItem 控件以在您的应用程序中使用。否则,您必须将其作为通用对象 ICheckable&lt;T&gt;(其中 T 是用户或角色)添加到列表中的项目中,并为您的项目添加 ICheckableCollection&lt;ICheckable&lt;T&gt;&gt;,而不是向模型对象添加可检查项。

      【讨论】:

      • 正确地说,我在谈论 ListView 和 ListViewItem,但几乎相同。你对海关课程的权利,我认为它不会那么复杂。但是要创建 ListView.CheckedItems,我需要遍历容器以查找已检查的容器,但我看不到这样做的方法。遍历项目并使用 GetContainerForItem 仅适用于 DependencyObject 类型的项目。有什么线索吗?
      猜你喜欢
      • 1970-01-01
      • 2014-09-29
      • 1970-01-01
      • 2010-09-10
      • 1970-01-01
      • 1970-01-01
      • 2019-05-21
      • 2014-08-14
      • 1970-01-01
      相关资源
      最近更新 更多