我正在使用WPF MVVM方法开发一个应用程序。 我有一个要求,需要在组合框中显示一系列项目以供选择。 根据某些标志,我需要过滤掉一些选择项。
我尝试使用两个不同的项目源,一个是完整列表,另一个是过滤列表,并根据标志来改变项目源。 这似乎效果不佳。是否有任何简单的方法可以基于某些标志对现有列表应用过滤器?
我正在使用WPF MVVM方法开发一个应用程序。 我有一个要求,需要在组合框中显示一系列项目以供选择。 根据某些标志,我需要过滤掉一些选择项。
我尝试使用两个不同的项目源,一个是完整列表,另一个是过滤列表,并根据标志来改变项目源。 这似乎效果不佳。是否有任何简单的方法可以基于某些标志对现有列表应用过滤器?
有很多不同的方法可以实现这个目标,但我个人偏好使用ListCollectionView
作为显示已过滤列表的控件的ItemsSource
,在ListCollectionView.Filter
上设置一个过滤器谓词,并在过滤参数更改时调用ListCollectionView.Refresh
。
以下示例将根据其所属的大陆过滤国家列表。
代码:
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;
public class FilteringViewModel : INotifyPropertyChanged
{
private ObservableCollection<Country> _countries;
private ContinentViewModel _selectedContinent;
public ListCollectionView CountryView { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<ContinentViewModel> Continents { get; set; }
public FilteringViewModel()
{
_countries =
new ObservableCollection<Country>(
new[]
{
new Country() { Continent = Continent.Africa, DisplayName = "Zimbabwe" },
new Country() { Continent = Continent.Africa, DisplayName = "Egypt" },
new Country() { Continent = Continent.Europe, DisplayName = "United Kingdom" }
});
CountryView = new ListCollectionView(_countries);
CountryView.Filter = o => _selectedContinent == null || ((Country)o).Continent == _selectedContinent.Model;
Continents = new ObservableCollection<ContinentViewModel>(Enum.GetValues(typeof(Continent)).Cast<Continent>().Select(c => new ContinentViewModel { Model = c}));
}
public ContinentViewModel SelectedContinent
{
get
{
return _selectedContinent;
}
set
{
_selectedContinent = value;
OnContinentChanged();
this.OnPropertyChanged("SelectedContinent");
}
}
private void OnContinentChanged()
{
CountryView.Refresh();
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class Country
{
public string DisplayName { get; set; }
public Continent Continent { get; set; }
}
public enum Continent
{
[Description("Africa")]
Africa,
Asia,
Europe,
America
}
public class ContinentViewModel
{
public Continent Model { get; set; }
public string DisplayName
{
get
{
return Enum.GetName(typeof(Continent), Model);
}
}
}
XAML
<StackPanel Orientation="Vertical">
<ComboBox ItemsSource="{Binding Continents}" SelectedItem="{Binding SelectedContinent}" DisplayMemberPath="DisplayName" />
<ListBox ItemsSource="{Binding CountryView}" DisplayMemberPath="DisplayName" />
</StackPanel>
public IEnumerable<ComboBoxItem> Data
{
get ;
set ;
}
ViewModel.Data.ToList().Where(item => item.Status).ToList()
状态可以是布尔值,基于此您可以筛选数据,并将此布尔值添加到您的ComboBoxItem类中。