35

Я использую a ObservableCollection с двумя ICollectionView для разных фильтров.WPF Multiple CollectionView с различными фильтрами в одной коллекции

Один для фильтрации сообщений каким-либо типом, а один для подсчета проверенных сообщений. Как вы можете видеть, фильтр сообщений и подсчет сообщений работают нормально, но когда я отменю проверку, сообщение исчезнет из списка (счет все еще работает).

Прошу прощения за длинный пост, я хотел включить все соответствующие материалы.

Часть XAML Код:

<!-- 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" /> 

Скриншот: enter image description here

Код:

/* 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 
} 

Код Для ун-че Функция ск

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

Dave это не столько ответ, но может помочь вам в будущем. Недавно я сделал несколько контрактов WPF, я просто не мог найти правильное решение для фильтрации, подкачки, сортировки, как я этого хотел. Я построил этот общий класс. Подумал, что тебе может нравиться трястись в нем. http://www.origin1.com/downloads/PagedObservableCollection.txt. очевидно, измените ext. – origin1tech

ответ

68

This answer помог мне с этой конкретной проблемы. Статический метод CollectionViewSource.GetDefaultView(coll) всегда будет возвращать одну и ту же ссылку для данной коллекции, поэтому использование нескольких видов коллекций в одной и той же ссылке будет контрпродуктивным. По инстанцировании мнение следующим образом:

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

мнение теперь могут быть отфильтрованы/отсортированы/сгруппированы независимо от любых других. Затем вы можете применить свою фильтрацию.

Я знаю, что прошло уже несколько месяцев, и вы, вероятно, решили проблему сейчас, но я столкнулся с этим вопросом, когда у меня была такая же проблема, поэтому я решил, что добавлю ответ.

+4

Спасибо, На самом деле это очень полезно, поскольку я не мог этого достичь, и это привело к большому уродливому обходу – drtf

+0

У меня проблема с этим методом: filterView, похоже, не соблюдает messageList, поэтому он не реагирует на какие-либо изменения в исходной коллекции –

 Смежные вопросы

  • Нет связанных вопросов^_^