2015-06-18 24 views
2

我已經ObservableCollection綁定到dataGrid,現在我想篩選提供的數據我知道我需要使用ICollectionView,但我不知道如何與我的MVVM添加模式ICollectionView過濾的ObservableCollection與ICollectionView

public class MainViewModel : ViewModelBase , IBarcodeHandler 
{ 
    public ObservableCollection<TraceDataItem> TraceItemCollectionViewSource { get; set; } 
} 

我的XAML

<Window xmlns:controls="clr-namespace:Mentor.Valor.vManage.RepairStation.Controls" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      <DataGrid Grid.Row="2" ColumnWidth="*" ItemsSource="{Binding TraceItemCollectionViewSource , Mode=TwoWay , UpdateSourceTrigger=PropertyChanged}" RowStyle="{StaticResource TraceRowStyle}" IsReadOnly="True" Name="TraceDataGrid" Margin="5,5,5,5" Padding="5,5,5,5" AutoGenerateColumns="False"> 
    </Window> 

我如何才能申請濾波的觀點在這裏添加ICollectionView

我的代碼如下簡化的外觀?

回答

5

你將需要:

public class MainViewModel : ViewModelBase, IBarcodeHandler 
{ 
    public ICollectionView TraceItemCollectionView 
    { 
     get { return CollectionViewSource.GetDefaultView(TraceItemCollectionViewSource); } 
    } 

    public ObservableCollection<TraceDataItem> TraceItemCollectionViewSource { get; set; } 
} 

然後,在代碼(也許在構造函數中)添加過濾器的地方:

TraceItemCollectionView.Filter = o => 
{ 
    var item = (TraceDataItem) o; 

    //based on item, return true if it should be visible, or false if not 

    return true; 
}; 

而且,XAML,你將需要改變綁定到TraceItemCollectionView屬性。

+0

@NightWalker是的。我更新了我的答案。 – Andrew

+0

所以每次我改變TraceItemCollectionViewSource我需要RaisePropertyChanged TraceItemCollectionView通知用戶界面? –

+0

@NightWalker是的。但是,ObservableCollection的整個觀點是你不需要改變它。 – Andrew

0

A CollectionView並不總是最好的解決方案。你也可以使用一些簡單的LinQ過濾你的集合。舉個簡單的例子:

public ObservableCollection<TraceDataItem> FilteredData 
{ 
    get 
    { 
     return new ObservableCollection<TraceDataItem>(YourUnfilteredCollection.Where(
      i => MeetsFilterRequirements(i))); 
    } 
} 

private bool MeetsFilterRequirements(TraceDataItem item) 
{ 
    return item.SomeProperty == someValue || item is SomeType; 
} 

這種方法的美妙之處在於您可以添加一些複雜的過濾要求。有一點需要注意:只要此方法中的任何屬性發生更改,您都需要致電NotifyPropertyChanged("FilteredData")以確保UI將相應更新。

+0

這將導致一個編譯時異常。 「Where」返回一個IEnumerable而不是一個集合。 – Andrew

+0

好點,謝謝...更新了我的代碼。 – Sheridan

+4

在我看來,這不是一個好的編輯。你最好返回一個IEnumerable。如果您每次都在創新ObservableCollection的目的是什麼? – Paparazzi

0

您可以調用一個命令的過濾回調和CollectionViewSource暴露View屬性:

public class ViewModel: INotifyPropertyChanged 
{ 
    private CollectionViewSource data = new CollectionViewSource(); 
    private ObservableCollection<Child> observableChilds = new ObservableCollection<Child>(); 

    public ViewModel() 
    { 
     var model = new Model(); 
     model.ChildList.Add(new Child { Name = "Child 1" }); 
     model.ChildList.Add(new Child { Name = "Child 2" }); 
     model.ChildList.Add(new Child { Name = "Child 3" }); 
     model.ChildList.Add(new Child { Name = "Child 4" }); 
     //Populate ObservableCollection 
     model.ChildList.ToList().ForEach(child => observableChilds.Add(child)); 

     this.data.Source = observableChilds; 
     ApplyFilterCommand = new DelegateCommand(OnApplyFilterCommand); 
    } 

    public ICollectionView ChildCollection 
    { 
     get { return data.View; } 
    } 

    public DelegateCommand ApplyFilterCommand { get; set; } 

    private void OnApplyFilterCommand() 
    { 
     data.View.Filter = new Predicate<object>(x => ((Child)x).Name == "Child 1"); 
     OnPropertyChanged("ChildCollection"); 
    } 
} 

//Sample Model used 
public class Model 
{ 
    public Model() 
    { 
     ChildList = new HashSet<Child>(); 
    } 

    public ICollection<Child> ChildList { get; set; } 
} 

public class Child 
{ 
    public string Name { get; set; } 
} 

//View 
<ListBox ItemsSource="{Binding Path = ChildCollection}" > 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Label Content="{Binding Name}"/> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

<Button Command="{Binding ApplyFilterCommand}"/> 
相關問題