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

时间:2010-05-05 16:04:12

标签: wpf xaml listview checkbox

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

我想在已选中状态和所选状态之间进行分离,因此我得到一个具有单个选定项目的ListBox,但可以有多个已检查项目。 不幸的是,ListViewItem没有用于检查的属性,我也没有看到使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.UncheckItem。

感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

好的,我明白了。 没什么可做的,但是因为我对整个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>

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

答案 1 :(得分:1)

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