35

Tôi đang sử dụng một ObservableCollection với hai ICollectionView cho các bộ lọc khác nhau.WPF Nhiều bộ sưu tậpXem với các bộ lọc khác nhau trên cùng một bộ sưu tập

Một là để lọc thư theo một số loại và một là để đếm thư đã kiểm tra. Như bạn có thể thấy bộ lọc tin nhắn và số lượng tin nhắn hoạt động OK, nhưng khi tôi không kiểm tra tin nhắn biến mất khỏi danh sách (số vẫn hoạt động).

BTW xin lỗi vì bài đăng dài, tôi muốn bao gồm tất cả nội dung có liên quan.

Bộ luật 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" /> 

Ảnh chụp màn hình: enter image description here

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 
} 

Mã Đối với un-che ck chức năng

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

Dave đây không phải là câu trả lời quá nhiều nhưng có thể giúp bạn xuống đường. Gần đây làm một số công việc hợp đồng WPF tôi chỉ không thể tìm thấy giải pháp đúng cho bộ lọc, phân trang, phân loại như tôi muốn nó. Tôi đã xây dựng lớp chung này. Nghĩ rằng bạn có thể thích poke xung quanh trong nó. http://www.origin1.com/downloads/PagedObservableCollection.txt. rõ ràng là thay đổi ext. – origin1tech

Trả lời

68

This answer giúp tôi với vấn đề này chính xác. Phương thức tĩnh CollectionViewSource.GetDefaultView(coll) sẽ luôn trả về cùng một tham chiếu cho một tập hợp nhất định, vì vậy việc căn cứ nhiều chế độ xem bộ sưu tập trên cùng một tham chiếu sẽ phản tác dụng. Bằng cách khởi tạo chế độ xem như sau:

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

Chế độ xem giờ đây có thể được lọc/sắp xếp/nhóm độc lập với bất kỳ người nào khác. Sau đó, bạn có thể áp dụng bộ lọc của mình.

Tôi biết đã vài tháng và bạn có thể giải quyết được vấn đề của mình ngay bây giờ, nhưng tôi đã xem xét câu hỏi này khi tôi gặp vấn đề tương tự vì vậy tôi đã tìm ra câu trả lời.

+4

Cảm ơn, Trên thực tế điều này rất hữu ích vì tôi không thể đạt được điều đó và kết quả với một giải pháp xấu lớn – drtf

+0

Tôi gặp vấn đề với phương pháp này: filterView dường như không quan sát messageList, vì vậy nó không phản ứng về bất kỳ thay đổi nào đối với thu thập nguồn –

Các vấn đề liên quan