2017-04-07 56 views
1

ViewModelクラスのエンティティと同じリストにバインドされたDataGridとComboBoxを持つWPF MVVMアプリケーションがあります。 ComboBoxの選択によってDataGridのエントリをフィルタリングしたいのですが、これを行う正しい方法は何ですか?私はMVVMで作業しているので、データバインディングでこれを実現し、無駄なコードを避けたいと思います。ComboBoxを使用したWPF MVVM DataGridフィルタリング

私のXAMLコードは、どのように私は、これらの値に異なることができ、私のコンボボックスは、URLの重複を示し、このコードで、また次

<DataGrid ItemsSource="{Binding Posts}" AutoGenerateColumns="False" IsReadOnly="True"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Id" Binding="{Binding Id}" /> 
     <DataGridTextColumn Header="Title" Binding="{Binding Title}" /> 
     <DataGridTextColumn Header="BlogUrl" Binding="{Binding Blog.Url}" /> 
    </DataGrid.Columns> 
</DataGrid> 

<ComboBox ItemsSource="{Binding Posts}" 
      DisplayMemberPath="Blog.Url" /> 

のViewModel

public class MainWindowViewModel 
{ 
    private SqliteDbContext context; 
    public List<Post> Posts { get; set; } 

    public MainWindowViewModel() 
    { 
     context = new SqliteDbContext(); 
     Posts = context.Posts.Include(p => p.Blog).ToList(); 
    } 
} 

のようなものですか?

ありがとうございました。

+0

REF別の[よう](http://stackoverflow.com/questions/5409259/binding-itemssource-of-a -comboboxcolumn-in-wpf-datagrid) –

答えて

1

ビューモデルで作成した一意のURLのコレクションにComboBoxをバインドできます。

その後、PostsソースコレクションをフィルタリングするビューモデルのソースプロパティにComboBoxSelectedItemプロパティを結合することによってDataGridをフィルタリングすることができます。

次のコードサンプルを参照してください。

ビューモデル:

public class MainWindowViewModel : INotifyPropertyChanged 
{ 
    private readonly SqliteDbContext context; 
    private readonly List<Post> _allPosts; 

    public MainWindowViewModel() 
    { 
     context = new SqliteDbContext(); 
     _allPosts = context.Posts.Include(p => p.Blog).ToList(); 
     _posts = _allPosts; 
     Urls = _allPosts.Where(p => p.Blog != null && !string.IsNullOrEmpty(p.Blog.Url)).Select(p => p.Blog.Url).ToList(); 
    } 

    private List<Post> _posts; 
    public List<Post> Posts 
    { 
     get { return _posts; } 
     set { _posts = value; NotifyPropertyChanged(); } 
    } 

    public List<string> Urls { get; set; } 

    private string _url; 
    public string Url 
    { 
     get { return _url; } 
     set 
     { 
      _url = value; NotifyPropertyChanged(); 
      Posts = _allPosts.Where(p => p.Blog != null && p.Blog.Url == _url).ToList(); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

ビュー:

<DataGrid ItemsSource="{Binding Posts}" AutoGenerateColumns="False" IsReadOnly="True"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Id" Binding="{Binding Id}" /> 
     <DataGridTextColumn Header="Title" Binding="{Binding Title}" /> 
     <DataGridTextColumn Header="BlogUrl" Binding="{Binding Blog.Url}" /> 
    </DataGrid.Columns> 
</DataGrid> 

<ComboBox ItemsSource="{Binding Urls}" SelectedItem="{Binding Url}" /> 
0

これはトリックを行う必要があります。

ビューモデル

public class MainWindowViewModel 
{ 
    private SqliteDbContext context; 

    public ObservableCollection<Post> Posts { get; set; } 
    private string _selectedUrl; 
    public ICollectionView PostsView { get; set; } 
    public MainWindowViewModel() 
    { 
     context = new SqliteDbContext(); 
     Posts = new ObservableCollection<Post>(context.Posts.Include(p => p.Blog)); 
     PostsView = new CollectionViewSource { Source = Posts }.View; 
     PostsView.Filter = post => SelectedUrl == null || SelectedUrl == ((Post)post).Blog.Url; 
    } 

    public string SelectedUrl 
    { 
     get 
     { 
      return _selectedUrl; 
     } 
     set 
     { 
      _selectedUrl = value; 
      PostsView.Refresh(); 
     } 
    } 
} 

XAML

<DataGrid ItemsSource="{Binding PostsView}" AutoGenerateColumns="False" IsReadOnly="True"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Id" Binding="{Binding Id}" /> 
     <DataGridTextColumn Header="Title" Binding="{Binding Title}" /> 
     <DataGridTextColumn Header="BlogUrl" Binding="{Binding Blog.Url}" /> 
    </DataGrid.Columns> 
</DataGrid> 

<ComboBox ItemsSource="{Binding Posts}" 
      DisplayMemberPath="Blog.Url" 
      SelectedValuePath="Blog.Url" 
      SelectedValue="{Binding SelectedUrl}"/> 
関連する問題