我有一个ObservableCollection<Model>
,其中填充了从文本文件中解析的对象。每个对象都是一条单独的行。当我将该集合绑定到控制器,例如列表框时,我想只显示一些特定的行,这些行在其模型中的布尔属性设置为true。例如:
型号:
class Model
{
public bool ShowText {get; set;}
public string Content {get; set;}
}
XAML:
<Listbox ItemsSource="{Binding LinesCollection}" <!-- A boolean property that will only display the objects whos ShowText is set to true --> />
答案 0 :(得分:3)
WPF执行此操作的方法是创建CollectionViewSource
,将其Source
属性设置为可观察集合,设置仅接受您感兴趣的项目的Filter
事件处理程序最后将ListBox
绑定到CollectionViewSource
。
有一个detailed example on MSDN显示了如何使用数据网格执行此操作,但同样的概念也适用于您的情况。
答案 1 :(得分:1)
有两种方法可以实现这一目标:
在视图模型中保留“主”和“视图”列表,并绑定到“视图”列表。无论何时更新主列表,视图列表都会在您拥有的任何条件下同步更新。
在列表中使用转换器为您过滤数据。你的转换函数看起来像:
return (value as IEnumerable).Where(l => somecondition);
绑定变为:
{Binding Path=LinesCollection, Converter={StaticResource FilterConverter}}
使用资源(假设您的转换器使用本地的xmlns命名空间):
<local:FilterLinesConverter x:Key="FilterConverter"/>
答案 2 :(得分:1)
简单方法:
将ListBox
的{{3}}设置为绑定到该媒体资源
<Window>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisConverter"/>
</Window.Resources>
<ListBox ItemsSource="{Binding LinesCollection}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Visibility" Value="{Binding ShowText, Converter={StaticResource BoolToVisConverter}}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Window>
更复杂的方法:使用ICollectionView
处理来自ViewModel的过滤,如其他答案中所述。
答案 3 :(得分:0)
创建另一个过滤数据的属性,并在主列表发生更改时返回列表。然后绑定到那个。
public List<strings> TrueLines
{
get { return LinesCollection.Where(ln => ln.ShowContent == true).ToList(); }
}
public List<Model> LinesCollection
{
get { ... }
set { OnPropertyChanged("LinesCollection");
OnPropertyChanged("TrueLines");
}
的Xaml
<Listbox ItemsSource="{Binding TrueLines}"
...从文本文件中解析的对象
为什么对象在可观察的集合中如果没有改变?上面的例子坚持这个逻辑。如果项目正在更改,则订阅可观察的集合更改通知,并在相关事件期间调用OnPropertyChanged("TrueLines");
。