我有一个带有DataGrid和ComboBox的WPF MVVM应用程序,这些应用程序绑定到ViewModel类中的相同实体列表。 我想通过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的重复项,如何区分这些值?
感谢。
答案 0 :(得分:1)
您可以将ComboBox
绑定到您在视图模型中创建的唯一网址的集合。
然后,您可以通过将DataGrid
的{{1}}属性绑定到过滤SelectedItem
源集合的视图模型的源属性来过滤ComboBox
。
请参阅以下代码示例。
查看型号:
Posts
查看:强>
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));
}
}
答案 1 :(得分:1)
这应该可以解决问题。
<强>视图模型强>:
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}"/>