繁体   English   中英

如何在WPF中过滤TreeView?

[英]How to filter a TreeView in WPF?

我在WPF TreeView上进行过滤时遇到麻烦。

这是我的TreeView XAML:

<TreeView x:Name="ResourcesTreeView" ItemsSource="{Binding Path=FilteredResources}">
<TreeView.Resources>
    <HierarchicalDataTemplate DataType="{x:Type models:HierarchicalResource}" ItemsSource="{Binding ContainedResources}">
        <StackPanel Orientation="Horizontal">
            <Image Source="{Binding ResourceIdentifier.ResourceType, Converter={StaticResource ResourceTypeToIconConverter}}" 
                Stretch="Uniform" Height="23" VerticalAlignment="Center"/>
            <TextBlock Text="{Binding Path=Name}" Style="{StaticResource ResourceName}" VerticalAlignment="Center"/>
        </StackPanel>
    </HierarchicalDataTemplate>
</TreeView.Resources>
<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectedItemChanged">
        <i:InvokeCommandAction Command="{Binding OnSelectedResourceChangedCommand}"
        CommandParameter="{Binding ElementName=ResourcesTreeView, Path=SelectedItem}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

这是HierarchicalResource类:

public class HierarchicalResource
{
    public HierarchicalResource(ResourceIdentifier resourceIdentifier, List<HierarchicalResource> containedResources, string name)
    {
        this.ResourceIdentifier = resourceIdentifier;
        this.ContainedResources = containedResources;
        this.Name = name;
    }

    public ResourceIdentifier ResourceIdentifier { get; }

    public List<HierarchicalResource> ContainedResources { get; set; }

    public string Name { get; }
}

这就是我如何初始化CollectionViewProperty的方法:

this.FilteredResources = CollectionViewSource.GetDefaultView(resourcesTree);

resourcesTree是一个包含一个根元素的列表,该根元素的ContainedResources属性包含多个子元素。 它看起来很棒。 唯一的问题是,尝试进行过滤时无法正常工作。 当我尝试使用this.FilteredResources.Filter = obj => {...}时,它仅在根节点上发生一次。 我如何真正使Filter委托在每个现有树节点上执行?

谢了,兄弟们

这将不适合一堆评论,因此我将尝试在答案中进行解释。 (我没有时间写一个完整的样本。)

从基础开始,这样您绝对可以了解我的意思。 树视图中的内容由树视图项组成。
treeviewitem是带标题的项目控件。 这就是为什么您看到的文本是“页眉”属性的原因。 在分层模板中,您有一个itemssource绑定。
这是父树viewitem内的itemscontrol的itemssource。
这就是造成您问题的原因。
如果是treeviewitems,则过滤的内容只是该顶层。
您没有在其中过滤项目控件。
或其中每个项目中的项目控件...等等。

这有两条路线。

您可以在视图中进行过滤。
要么
您可以在视图模型中进行过滤。

让我们先谈谈ViewModel
您绑定到列表。
当您这样做时,会自动生成一个collectionview。
您可以对此进行参考,并对其应用过滤器。 几乎就像他们设计了这个一样,您可以轻松地进行绑定,但是需要进行更多工作,并且可以对+进行排序。

您应该对此做一点点谷歌,但是松散地说这就像:

var view1 = CollectionViewSource.GetDefaultView(source);

您可能必须强制转换为collectionview或listcollectionview。 这些具有谓词过滤。 像这样:
https://social.technet.microsoft.com/wiki/contents/articles/26673.wpf-collectionview-tips.aspx#Filtering
该文章有一个示例,您可以根据列表绑定到显式collectionview。

或者。
您可以在视图中执行此操作。
我建议您看一下,但是要进行viewmodel过滤。

这比较困难,但是这意味着您的过滤器可以在XAML中使用。 我这样做的方式是使用转换器,但是这也是一个框架元素。 像这样http://drwpf.com/blog/category/value-converters/

它也可以具有转换器可以使用的一个或多个属性。
这是一个除数转换器:

public class DivideByConverter : MarkupExtension, IValueConverter
{
    public double Divisor { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double bound = System.Convert.ToDouble(value);
        return bound / Divisor;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

用过的:

<ScaleTransform ScaleX="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=Button}
    , Converter={local:DivideByConverter Divisor=480}
    }" 

为什么需要财产?
您需要某种方式来传递谓词,以便转换器可以为您过滤列表。
在WPF中,您是否可以过滤CollectionViewSource而无需编写代码?

您甚至可以列出谓词。
向转换器添加属性的技术非常有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM