35

मैं विभिन्न फ़िल्टरों के लिए ObservableCollection के साथ ICollectionView का उपयोग कर रहा हूं।WPF एकाधिक संग्रह दृश्य एक ही संग्रह पर विभिन्न फ़िल्टर के साथ

कोई किसी प्रकार से संदेशों को फ़िल्टर करने के लिए है, और एक चेक किए गए संदेशों की गणना करने के लिए है। जैसा कि आप संदेश फ़िल्टर और संदेश गिनती देख सकते हैं ठीक है, लेकिन जब मैं अनदेखा कर रहा हूं तो संदेश सूची से गायब हो जाता है (गणना अभी भी पर काम कर रही है)।

बीटीडब्ल्यू लंबे पद के लिए खेद है, मैं सभी प्रासंगिक सामान शामिल करना चाहता था।

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

डेव यह इतना जवाब नहीं है लेकिन सड़क पर आपकी मदद कर सकता है। हाल ही में कुछ डब्ल्यूपीएफ अनुबंध काम कर रहे हैं, मुझे फिल्टर, पेजिंग, सॉर्टिंग के लिए सही समाधान नहीं मिला क्योंकि मैं चाहता था। मैंने इस जेनेरिक वर्ग का निर्माण किया। सोचा था कि आप इसमें चारों ओर पोक करना पसंद कर सकते हैं। 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

मुझे इस विधि के साथ कोई समस्या है: फ़िल्टर किए गए दृश्य संदेश सूची को नहीं देख रहे हैं, इसलिए यह स्रोत संग्रह में किसी भी बदलाव पर प्रतिक्रिया नहीं करता है –

संबंधित मुद्दे