代码之家  ›  专栏  ›  技术社区  ›  Marks

WPF-使用可检查和可选择的ListViewItems扩展ListView

  •  2
  • Marks  · 技术社区  · 16 年前

    我想在选中状态和选中状态之间有一个分隔,所以我得到一个列表框,它有一个选中的项目,但可以有多个选中的项目。 不幸的是,ListViewItem没有checked的属性,我认为不可能让ListView与自定义的CheckableListViewItem一起工作。

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

    我想要的行为可以很容易地用一个

    <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.uncheckItems。

    谢谢你的帮助。

    2 回复  |  直到 16 年前
        1
  •  4
  •   Marks    16 年前

    好的,我知道了。 虽然没什么要做的,但因为我对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(clr=my class namespace)下插入XAML:

    <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
  •  1
  •   Jeff Wain    16 年前

    为此,您必须创建一个自定义 ListBox 和习俗 ListBoxItem ICheckable<T> ICheckableCollection<ICheckable<T>>

    推荐文章