2017-12-21 32 views
0

昨日、私はDataGridをフィルタリングするための検索バーを作っていました。私はこれを行うことに成功しましたが、今日私がそれを見ていたとき、なぜそれが働いているのか分かりませんでした。ここに私を混乱させるものがあります:WPF MVVMでDataGridをフィルタリングしても動作しますが、理由はわかりません

基本的に私は、そのItemsSourceがEquipmentというObservableCollectionに設定されたDataGridを持っています。 Equipmentsをフィルタリングするために、EquipmentViewというICollectionViewも作成しました。このICollectionViewは、フィルタリングを行うことができるEquipmentsのミラーです。

機器は、このように私のデータベース内のテーブルからのviewmodelに移入されています

public async Task LoadAsync() 
    { 
     try 
     { 
      var lookup = await _equipmentLookupDataService.GetEquipmentLookupAsync(); 
      Equipments.Clear(); 
      foreach (var item in lookup) 
      { 
       Equipments.Add(item); 
      } 
      EquipmentView = CollectionViewSource.GetDefaultView(Equipments); 
      EquipmentView.Filter = new Predicate<object>(Filter); 
     } 
     catch (Exception e) 
     { 
      MessageBox.Show(e.Message, "An error occurred", MessageBoxButton.OK, MessageBoxImage.Warning); 
      //create new error object from the exception and add to DB 
      Error error = new Error 
      { 
       ErrorMessage = e.Message, 
       ErrorTimeStamp = DateTime.Now, 
       ErrorStackTrace = e.StackTrace, 
       LoginId = CurrentUser.LoginId 
      }; 
      await _errorDataService.AddError(error); 
     } 
    } 

Filterメソッドを呼び出しますEquipmentView.Filter:

public bool Filter(object obj) 
    { 
     var data = obj as EquipmentLookup; 

     if (EquipmentView != null) 
     { 
      if (!string.IsNullOrEmpty(_filterString)) 
      { 
       string allcaps = _filterString.ToUpper(); 
       return data.TypeName.StartsWith(_filterString) || data.TypeName.StartsWith(allcaps); 
      } 
      return true; 
     } 
     return false; 
    } 

それはときにのみ型名プロパティが始まるtrueを返しますfilterstringは検索バーにバインドされた文字列です。

今私はDataViewのItemsSourceをEquipmentViewに設定しなければならなかったと思っています。私がすれば、すべてうまく動作し、データグリッドは検索バーと一致するものだけを表示します。

明らかに、データグリッド上のitemsSourceをEquipmentsに戻しても、検索バーはまだ機能しています。どうしてこれなの?私が知っている限り、EquipmentViewのフィルタリングは、Equipmentについて何も変更してはいけませんが、とにかくそうするようです。

すべてがうまくいきます検索バーのためにも

XAMLコード:

<TextBox Name="SearchBar" Margin="10 10 10 10" Text="{Binding FilterString, UpdateSourceTrigger=PropertyChanged}"/> 

データグリッド:WPFのドキュメントから

 <DataGrid MaxHeight="800" 
      ItemsSource="{Binding Equipments}" 
      SelectedItem="{Binding SelectedEquipment, Mode=TwoWay}" 
      IsReadOnly="True" 
      CanUserReorderColumns="False" 
      SelectionMode="Single" 
      ColumnWidth="*"> 
      <DataGrid.ItemContainerStyle> 
       <Style TargetType="DataGridRow"> 
        <EventSetter Event="MouseDoubleClick" 
        Handler="Row_DoubleClick" /> 
       </Style> 
      </DataGrid.ItemContainerStyle> 
     </DataGrid> 
+2

。ビューは、フィルタ、並べ替えなどを可能にする単なるラッパーです。 – Manolo

答えて

3

すべてのコレクションは、デフォルトCollectionViewを持っています。 WPFは常にコレクションではなく ビューにバインドします。コレクションに直接バインドする場合、 WPFは実際にそのコレクションの既定のビューにバインドします。この デフォルトビューは、コレクションへのすべてのバインディングによって共有され、 コレクションへのすべての直接バインディングは、ソート、フィルタ、グループ グループ、および1つのデフォルトビューの現在のアイテム特性を共有します。あなたのコードで今すぐ

は、あなたはこれをやっている:あなたはコレクションにバインドすると、WPFが実際にそのコレクションの既定のビューに結合され

EquipmentView = CollectionViewSource.GetDefaultView(Equipments); 
EquipmentView.Filter = new Predicate<object>(Filter); 
関連する問題