2010-05-05 71 views
2

我已经阅读了很多关于使用与IsSelected绑定的复选框来扩展ListView的例子。但我想要更多。WPF - 使用可选和可选ListViewItems扩展ListView

我想检查和选择状态之间的分离,所以我得到一个ListBox有一个选定的项目,但可以有多个检查项目。 不幸的是,ListViewItem没有检查属性,我看不到有可能使ListView与自定义的CheckableListViewItem一起工作。

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

我想要的行为可以easyly accomblished的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。

感谢您的任何帮助。

回答

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

插入到你的XAML下Window.Resources(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> 

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

1

为了做到这一点,您必须创建自定义ListBox和自定义ListBoxItem控件以在您的应用程序中使用。否则,您将不得不将其添加到列表中的项目中作为通用对象ICheckable<T>(其中T是用户或角色),并且您的项目具有ICheckableCollection<ICheckable<T>>,而不是向模型对象添加可检查项。

+0

只是为了正确,即时通讯谈论ListView和ListViewItem,但它几乎相同。你的海关课程权利,我认为它不会那么复杂。但是为了创建一个ListView.CheckedItems,我需要遍历容器来查找已检查的容器,而我没有办法做到这一点。遍历项目并使用GetContainerForItem仅适用于DependencyObject类型的项目。任何线索? – Marks 2010-05-06 09:17:43