WPF多的CollectionView对同一个集合不同的过滤器 [英] WPF Multiple CollectionView with different filters on same collection

查看:1077
本文介绍了WPF多的CollectionView对同一个集合不同的过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是一个的ObservableCollection 有两个的ICollectionView 为不同的过滤器。

一个是由某种类型的过滤消息,以及一个用于计数检验消息。
正如你所看到的消息过滤器和消息计数工作确定,但是当我取消选中该邮件从列表中消失(计数仍正常工作的)。

BTW对长期职位对不起,我想包括所有相关的东西。

的XAML code:

 <! - 信息列表 - >
&所述; DockPanel中Grid.Row =1
           Grid.Column =0
           Grid.ColumnSpan =3
           HEIGHT =500>
  <列表框名称=listBoxZone
           的ItemsSource ={结合filteredMessageList}
           背景=透明
           了borderThickness =0>
    < ListBox.ItemTemplate>
      <&DataTemplate的GT;
        <复选框名称=CheckBoxZone
                  CONTENT ={结合文字}
                  标签={绑定ID}
                  未选中=CheckBoxZone_Unchecked
                  前景=的WhiteSmoke
                  保证金=0,5,0,0
                  =器isChecked{结合}器isChecked/>
      < / DataTemplate中>
    < /ListBox.ItemTemplate>
  < /列表框>
< / DockPanel中>
<按钮内容=测试新增
        Grid.Column =2
        HEIGHT =25
        的Horizo​​ntalAlignment =左
        保证金=34,2,0,0
        点击=的button1_Click/>
<标签内容={结合checkedMessageList.Count}
       Grid.Column =2
       HEIGHT =25
       保证金=147,2,373,0
       宽度=20
       前景=白/>

截图:

code:

  / * ViewModel类* /
公共类MainViewModel:INotifyPropertyChanged的
{    //构造
    公共MainViewModel()
    {
        #区域filteredMessageList
        //连接到的ObservableCollection的CollectionView
        _filteredMessageList = CollectionViewSource.GetDefaultView(给messageManager);
        //设置过滤器
        _filteredMessageList.Filter =委托(对象项)
        {
            MessageClass的TEMP =项目作为MessageClass的;            如果(selectedFilter.Equals(AvailableFilters.All))
            {
                返回true;
            }
            其他
            {
                返回temp.filter.Equals(_selectedFilter);
            }
        };
        #endregion        #区域checkedMessageList
        //连接到的ObservableCollection的CollectionView
        _checkedMessageList = CollectionViewSource.GetDefaultView(给messageManager);
        //设置过滤器
        _checkedMessageList.Filter =委托(对象项){回报(项目作为MessageClass的).isChecked; };
        #endregion
    }    //留言列表
    私人的ObservableCollection<&MessageClass的GT; _messageList =
            新的ObservableCollection<&MessageClass的GT;();
    公众的ObservableCollection<&MessageClass的GT;给messageManager
    {
        {返回_messageList; }
        集合{_messageList =价值; }
    }    //的CollectionView(过滤给messageManager)
    私人的ICollectionView _filteredMessageList;
    公众的ICollectionView filteredMessageList
    {
        {返回_filteredMessageList; }
    }    //的CollectionView(过滤给messageManager)
    私人的ICollectionView _checkedMessageList;
    公众的ICollectionView checkedMessageList
    {
        {返回_checkedMessageList; }
    }    // SelectedFilter财产
    私人AvailableFilters _selectedFilter = AvailableFilters.All; //默认设置为所有
    公共AvailableFilters selectedFilter
    {
        {返回_selectedFilter; }
        组
        {
            _selectedFilter =价值;
            RaisePropertyChanged(selectedFilter);
            _filteredMessageList.Refresh(); //刷新后更新列表
        }
    }    // FilterList(转换枚举集)
    私人列表< KeyValuePair<字符串,AvailableFilters>> _AvailableFiltersList;
    公开名单< KeyValuePair<字符串,AvailableFilters>> AvailableFiltersList
    {
        得到
        {
            / *检查如列表中可用,如果不是因为第一次使用*创建/
            如果(_AvailableFiltersList == NULL)
            {
                _AvailableFiltersList =新的List< KeyValuePair<字符串,AvailableFilters>>();
                的foreach(在Enum.GetValues​​ AvailableFilters过滤器(typeof运算(AvailableFilters)))
                {
                    字符串描述;
                    。字段信息字段信息= filter.GetType()getfield命令(filter.ToString());
                    DescriptionAttribute [] =属性
                                (DescriptionAttribute [])fieldInfo.GetCustomAttributes(typeof运算(DescriptionAttribute),FALSE);                    / *如果不为null GET说明* /
                    如果(属性=空&放大器;!&放大器; attributes.Length大于0)
                    {
                        说明=属性[0]。说明;
                    }
                    其他
                    {
                        说明=的String.Empty;
                    }                    / *为新项目添加到filterList * /
                    KeyValuePair<字符串,AvailableFilters> TypeKeyValue =
                                新KeyValuePair<字符串,AvailableFilters>(描述,过滤器);                    _AvailableFiltersList.Add(TypeKeyValue);
                }
            }
            返回_AvailableFiltersList;
        }
    }    #REGION实现INotifyPropertyChanged
    公共事件PropertyChangedEventHandler的PropertyChanged;
    公共无效RaisePropertyChanged(字符串propertyName的)
    {
        PropertyChangedEventHandler处理器=的PropertyChanged;
        如果(!=处理空值)处理器(这一点,新PropertyChangedEventArgs(propertyName的));
    }
    #endregion
}

code对于未检查功能

 私人无效CheckBoxZone_Unchecked(对象发件人,RoutedEventArgs E)
{
    复选框chkZone =(复选框)发送;
    ucSystemMessageVM.checkedMessageList.Refresh();
}


解决方案

这个答案帮我这个确切的问题。静态GetDefaultView()方法总是返回一个给定集合相同的参考,所以基于同一基准的多个集合视图会适得其反。通过实例的观点如下:

 的ICollectionView filteredView =新CollectionViewSource {源=给messageManager} .View;

该视图现在可以过滤/排序/分组独立于任何其他人。那么你可以申请你的过滤。

我知道它已经一两个月,你都可能已经解决您的问题,但我碰到这个问题的时候跑到我有同样的问题,所以我想我会添加一个答案。

I'm using a an ObservableCollection with two ICollectionView for different filters.

One is for filtering messages by some type, and one is for counting checked messages. As you can see message filter and message count works OK, but when I'm un-checking the message disappear from the list (the count is still working).

BTW sorry for the long post, I wanted to include all relevant stuff.

The XAML Code:

<!-- Messages List -->
<DockPanel Grid.Row="1"
           Grid.Column="0"
           Grid.ColumnSpan="3"
           Height="500">
  <ListBox Name="listBoxZone"
           ItemsSource="{Binding filteredMessageList}"
           Background="Transparent"
           BorderThickness="0">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <CheckBox Name="CheckBoxZone"
                  Content="{Binding text}"
                  Tag="{Binding id}"
                  Unchecked="CheckBoxZone_Unchecked"
                  Foreground="WhiteSmoke"
                  Margin="0,5,0,0"
                  IsChecked="{Binding isChecked}" />
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</DockPanel>
<Button Content="Test Add New"
        Grid.Column="2"
        Height="25"
        HorizontalAlignment="Left"
        Margin="34,2,0,0"
        Click="button1_Click" />
<Label Content="{Binding checkedMessageList.Count}"
       Grid.Column="2"
       Height="25"
       Margin="147,2,373,0"
       Width="20"
       Foreground="white" />

Screenshot:

Code:

/* ViewModel Class */
public class MainViewModel : INotifyPropertyChanged
{

    // Constructor
    public MainViewModel()
    {
        #region filteredMessageList
        // connect the ObservableCollection to CollectionView
        _filteredMessageList = CollectionViewSource.GetDefaultView(messageList);
        // set filter 
        _filteredMessageList.Filter = delegate(object item)
        {
            MessageClass temp = item as MessageClass;

            if ( selectedFilter.Equals(AvailableFilters.All) )
            {
                return true;
            }
            else
            {
                return temp.filter.Equals(_selectedFilter);
            }
        };
        #endregion

        #region checkedMessageList
        // connect the ObservableCollection to CollectionView
        _checkedMessageList = CollectionViewSource.GetDefaultView(messageList);
        // set filter 
        _checkedMessageList.Filter = delegate(object item) { return (item as MessageClass).isChecked; };
        #endregion
    }

    // message List
    private ObservableCollection<MessageClass> _messageList =
            new ObservableCollection<MessageClass>();
    public ObservableCollection<MessageClass> messageList
    {
        get { return _messageList; }
        set { _messageList = value; }
    }

    // CollectionView (filtered messageList)
    private ICollectionView _filteredMessageList;
    public ICollectionView filteredMessageList
    {
        get { return _filteredMessageList; }
    }

    // CollectionView (filtered messageList)
    private ICollectionView _checkedMessageList;
    public ICollectionView checkedMessageList
    {
        get { return _checkedMessageList; }
    }

    // SelectedFilter property
    private AvailableFilters _selectedFilter = AvailableFilters.All; // Default is set to all
    public AvailableFilters selectedFilter
    {
        get { return _selectedFilter; }
        set
        {
            _selectedFilter = value;
            RaisePropertyChanged("selectedFilter");
            _filteredMessageList.Refresh(); // refresh list upon update
        }
    }

    // FilterList (Convert Enum To Collection)
    private List<KeyValuePair<string, AvailableFilters>> _AvailableFiltersList;
    public List<KeyValuePair<string, AvailableFilters>> AvailableFiltersList
    {
        get
        {
            /* Check if such list available, if not create for first use */
            if (_AvailableFiltersList == null)
            {
                _AvailableFiltersList = new List<KeyValuePair<string, AvailableFilters>>();
                foreach (AvailableFilters filter in Enum.GetValues(typeof(AvailableFilters)))
                {
                    string Description;
                    FieldInfo fieldInfo = filter.GetType().GetField(filter.ToString());
                    DescriptionAttribute[] attributes =
                                (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

                    /* if not null get description */
                    if (attributes != null && attributes.Length > 0)
                    {
                        Description = attributes[0].Description;
                    }
                    else
                    {
                        Description = string.Empty;
                    }

                    /* add as new item to filterList */
                    KeyValuePair<string, AvailableFilters> TypeKeyValue =
                                new KeyValuePair<string, AvailableFilters>(Description, filter);

                    _AvailableFiltersList.Add(TypeKeyValue);
                }
            }
            return _AvailableFiltersList;
        }
    }

    #region Implement INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

Code For un-check function

private void CheckBoxZone_Unchecked(object sender, RoutedEventArgs e)
{
    CheckBox chkZone = (CheckBox)sender;
    ucSystemMessageVM.checkedMessageList.Refresh();
}

解决方案

This answer helped me with this exact problem. The static GetDefaultView() method will always return the same reference for a given collection, so basing multiple collection views on the same reference will be counterproductive. By instantiating the view as follows:

ICollectionView filteredView = new CollectionViewSource { Source=messageList }.View;

The view can now be filtered/sorted/grouped independently of any others. Then you can apply your filtering.

I know it's been a couple months and you have probably solved your problem by now, but I ran across this question when I had the same problem so I figured I would add an answer.

这篇关于WPF多的CollectionView对同一个集合不同的过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆