filtro filtrar c# wpf observablecollection collectionviewsource icollectionview

filtro - filtrar datagridview c#



WPF Multiple CollectionView con diferentes filtros en la misma colección (1)

Estoy usando un ObservableCollection con dos ICollectionView para diferentes filtros.

Una es para filtrar mensajes de algún tipo, y otra para contar mensajes marcados. Como puede ver, el conteo del mensaje y el filtro de mensajes funciona bien, pero cuando estoy desmarcando el mensaje desaparece de la lista ( el recuento sigue funcionando ).

Por cierto, perdón por la publicación larga, quería incluir todas las cosas relevantes.

El código 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" />

Captura de pantalla:

Código:

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

Código para la función de desconexión

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


Esta respuesta me ayudó con este problema exacto. El método estático CollectionViewSource.GetDefaultView(coll) siempre devolverá la misma referencia para una colección determinada, por lo que basar varias vistas de colección en la misma referencia será contraproducente. Al crear una instancia de la vista de la siguiente manera:

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

La vista ahora puede ser filtrada / clasificada / agrupada independientemente de cualquier otra. Luego puedes aplicar tu filtrado.

Sé que han pasado un par de meses y probablemente ya hayas resuelto tu problema, pero me encontré con esta pregunta cuando tuve el mismo problema, así que pensé que iba a agregar una respuesta.