[英]WPF MVVM DataGrid filtering using ComboBox
我有一個WPF MVVM應用程序,它具有綁定到ViewModel類中相同實體列表的DataGrid和ComboBox。 我想通過ComboBox選擇過濾DataGrid條目,正確的方法是什么? 由於我使用的是MVVM,因此我想通過數據綁定來實現這一點,並避免使用無用的代碼。
我的XAML代碼如下所示
<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" />
視圖模型
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();
}
}
另外,使用此代碼,我的ComboBox顯示了Urls的重復項,如何區分這些值?
謝謝。
您可以將ComboBox
綁定到您在視圖模型中創建的唯一URL的集合。
然后,可以通過將ComboBox
的SelectedItem
屬性綁定到用於過濾Posts
源集合的視圖模型的source屬性來過濾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}" />
這應該可以解決問題。
ViewModel :
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}"/>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.