2017-02-14 63 views
0

在我的WPF Window我有一個DataGrid控制過濾一個DataGrid,其ItemsSource綁定到項目的一個ObservableCollection(比方說有幾個屬性的簡單對象):WPF:在飛行

XAML:(去掉了一些東西的xmlns爲簡潔起見)

<Window> 
    <Window.Resources> 
     <CollectionViewSource x:Key="MyViewSource" 
           Source="{Binding MyItemList}" 
           Filter="MyItemList_Filter"/> 
    </Window.Resources> 

    <Window.DataContext> 
     <!-- Some Ioc stuff --> 
    </Window.DataContext> 

    <StackPanel> 
     <TextBox Text="{Binding TextFilter}" /> 
     <DataGrid Grid.Row="1" x:Name="dataGrid" 
      ItemsSource="{Binding Source={StaticResource MyViewSource}}" 
      SelectionUnit="FullRow" 
      SelectionMode="Extended" 
      CanUserAddRows="False" 
      CanUserDeleteRows="False" 
      HeadersVisibility="Column" /> 
    </StackPanel> 
</Window> 

視圖模型(CS):

public class ViewModel : ViewModelBase // From Galasoft MVVM Light toolkit 
{ 

    #region TextFilter Property 
    public const string TextFilterPropertyName = "TextFilter"; 

    private string _TextFilter; 

    public string TextFilter 
    { 
     get 
     { 
      return _TextFilter; 
     } 

     set 
     { 
      if (_TextFilter == value) 
      { 
       return; 
      } 

      _TextFilter = value; 

      RaisePropertyChanged(TextFilterPropertyName); 
     } 
    } 
    #endregion // TextFilter Property 

    #region MyItemList Property 
    public const string MyItemListPropertyName = "MyItemList"; 

    private ObservableCollection<Item> _MyItemList; 

    public ObservableCollection<Item> MyItemList 
    { 
     get 
     { 
      return _MyItemList; 
     } 

     set 
     { 
      if (_MyItemList == value) 
      { 
       return; 
      } 

      _MyItemList = value; 

      RaisePropertyChanged(MyItemListPropertyName); 
     } 
    } 
    #endregion // MyItemList Property 


} 

篩選方法,從窗口的後面的代碼:填充MyItemList

private void MyItemList_Filter(object sender, FilterEventArgs e) 
{ 
    var vm = (ViewModel)this.DataContext; 
    var item = (Item)e.Item; 
    // ...Simplified... 
    e.Accepted = item.PropertyToCheck.Contains(vm.TextFilter); 
} 

濾波僅應用於:我怎樣才能使MyItemList_Filter被上稱爲(和DataGrid項被顯示/相應隱藏)「活「TextFilter更改?

任何幫助,將不勝感激

回答

2

你可以(應該)移動過濾邏輯視圖模型,例如:

public class ViewModel : ViewModelBase 
{ 
    public const string TextFilterPropertyName = "TextFilter"; 

    private string _TextFilter; 
    public string TextFilter 
    { 
     get 
     { 
      return _TextFilter; 
     } 
     set 
     { 
      if (_TextFilter == value) 
       return; 
      _TextFilter = value; 
      RaisePropertyChanged(TextFilterPropertyName); 
      Filter(); 
     } 
    } 

    public const string MyItemListPropertyName = "MyItemList"; 

    private ObservableCollection<Item> _MyItemList; 
    public ObservableCollection<Item> MyItemList 
    { 
     get 
     { 
      return _MyItemList; 
     } 
     set 
     { 
      if (_MyItemList == value) 
       return; 

      _MyItemList = value; 
      RaisePropertyChanged(MyItemListPropertyName); 
     } 
    } 

    private ObservableCollection<Item> _filtered; 
    public ObservableCollection<Item> FilteredList 
    { 
     get 
     { 
      return _filtered; 
     } 
     set 
     { 
      if (_filtered == value) 
       return; 

      _filtered = value; 
      RaisePropertyChanged("FilteredList"); 
     } 
    } 

    private void Filter() 
    { 
     _filtered.Clear(); 
     foreach(var item in _MyItemList) 
     { 
      if (item.PropertyToCheck.Contains(TextFilter)) 
       _filtered.Add(item); 
     } 
    } 
} 

這就是原來的位置。那麼你不需要CollectionViewSource:

<DataGrid Grid.Row="1" x:Name="dataGrid" ItemsSource="{Binding FilteredList}" ... /> 
+0

這很有效,謝謝。你說過濾是一個ViewModel相關的東西,但我幾乎不同意... –

+2

如果你有任何自定義過濾邏輯,這肯定會在視圖模型中,如果你打算承認MVVM模式。如果您實現一些非常通用的過濾器功能,例如控件功能的一部分,則可能出現異常。但是,如果您基於視圖模型中某個屬性的值進行過濾,則應該在視圖模型中實施過濾邏輯。 – mm8