答案 0 :(得分:3)
修改强>
最后,我已经满足了你的要求。
Here is the link to the updated project
(由卢克编辑)
这是我最终选择的(优秀)解决方案,因此我将提取重要部分,并实际上将它们作为帖子的一部分:
关键的xaml部分最终看起来像这样:
<CollectionViewSource x:Key="FooCVS" x:Name="_fooCVS" Source="{Binding Foos, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type WpfApplication1:MainWindow}}}" Filter="_fooCVS_Filter"/>
<CollectionViewSource x:Key="BarCVS" x:Name="_barCVS" Source="{Binding Bars, Source={StaticResource FooCVS}}" Filter="_barCVS_Filter"/>
<CollectionViewSource x:Key="QuxCVS" x:Name="_quxCVS" Source="{Binding Quxs, Source={StaticResource BarCVS}}" Filter="_quxCVS_Filter"/>
我将相应的控件设置为每个视图作为控件的ItemSource
。神奇的是每个CVS的绑定。每个CVS都会获取出现的控件/模板控件的数据上下文,因此您可以使用绑定对象集合的真实名称。我不确定我理解为什么绑定源绑定源自身(CVS)的工作原理,但它确实如此美妙。
过滤器TextBox
的代码就变成了:
private void filterTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var cvs = TryFindResource("FooCVS") as CollectionViewSource;
if (cvs != null)
{
if (cvs.View != null)
cvs.View.Refresh();
}
cvs = TryFindResource("QuxCVS") as CollectionViewSource;
if (cvs != null)
{
if (cvs.View != null)
cvs.View.Refresh();
}
cvs = TryFindResource("BarCVS") as CollectionViewSource;
if (cvs != null)
{
if (cvs.View != null)
cvs.View.Refresh();
}
}
优秀的解决方案,因为它不需要更改底层对象或层次结构。
答案 1 :(得分:2)
答案 2 :(得分:0)
我今天的工作遇到了类似的问题,并提出了以下解决方案:
直接或通过适配器模式为所有元素添加Visibility属性。
Visibility Visibility
{
get { return visibility; }
set { visibility = value; PropertyChanged("Visibility"); }
}
将控件的Vis Visibility属性绑定到step1中相应的Visibility属性。
通过扩展方法或内部对数据实施简单过滤。
void Filter(Func<Foo, bool> filterFunc)
{
foreach (var item in foos)
{
if (!filterFunc(item))
item.Visibility = Visibility.Collapsed;
else
item.Visibility = Visibility.Visible;
}
}
在TextBox的TextChanged事件上添加简单的过滤器调用。
过滤器(n =&gt; n.Name.ToLower()。包含(textBox.Text));
或者对容器控件更高级:
Filter(c => c.Items.Any(i => i.Visibility == Visibility.Visible));