使用带有 HierarchicalDataTemplate 的 CollectionViewSource

pas*_*man 8 wpf hierarchicaldatatemplate collectionviewsource

您将如何将 CollectionViewSource(用于提供排序行为)与 HierarchicalDataTemplate 的 ItemsSource 结合使用?

因此,鉴于下面的代码,我如何对层次结构中每个级别的子级应用排序?

<HierarchicalDataTemplate DataType="{x:Type l:CommandGroup}"
                          ItemsSource="{Binding Children}">
                    <HierarchicalDataTemplate.ItemContainerStyle>
                        <Style TargetType="{x:Type MenuItem}"
                               BasedOn="{StaticResource {x:Type MenuItem}}">
                            <Setter Property="Command"
                                    Value="{Binding Command}" />
                            <Setter Property="CommandParameter"
                                    Value="{Binding}" />
                        </Style>
                    </HierarchicalDataTemplate.ItemContainerStyle>
                    <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
Run Code Online (Sandbox Code Playgroud)

我以为我可能能够执行以下操作,但它使后代无法显示并产生以下绑定错误。

<HierarchicalDataTemplate DataType="{x:Type l:CommandGroup}">
                    <HierarchicalDataTemplate.ItemsSource>
                        <Binding>
                            <Binding.Source>
                                <CollectionViewSource Source="{Binding Children}" />
                            </Binding.Source>
                        </Binding>
                    </HierarchicalDataTemplate.ItemsSource>
                    <HierarchicalDataTemplate.ItemContainerStyle>
                        <Style TargetType="{x:Type MenuItem}"
                               BasedOn="{StaticResource {x:Type MenuItem}}">
                            <Setter Property="Command"
                                    Value="{Binding Command}" />
                            <Setter Property="CommandParameter"
                                    Value="{Binding}" />
                        </Style>
                    </HierarchicalDataTemplate.ItemContainerStyle>
                    <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Children; DataItem=null; target element is 'CollectionViewSource' (HashCode=5114324); target property is 'Source' (type 'Object')
Run Code Online (Sandbox Code Playgroud)

编辑:我最终得到了以下内容-希望对其他人有所帮助

 <Window.Resources>
    <l:SortedCollectionViewSource x:Key="SortedCollectionViewSource" Property="Name"/>
</Window.Resources>

<Window.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Add new item..."
                  ItemsSource="{Binding AddNewItem.Children, Converter={StaticResource SortedCollectionViewSource}}">
            <MenuItem.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type l:CommandGroup}"
                                          ItemsSource="{Binding Children, Converter={StaticResource SortedCollectionViewSource}}">
                    <HierarchicalDataTemplate.ItemContainerStyle>
                        <Style TargetType="{x:Type MenuItem}"
                               BasedOn="{StaticResource {x:Type MenuItem}}">
                            <Setter Property="Command"
                                    Value="{Binding Command}" />
                            <Setter Property="CommandParameter"
                                    Value="{Binding}" />
                        </Style>
                    </HierarchicalDataTemplate.ItemContainerStyle>
                    <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
            </MenuItem.ItemTemplate>
        </MenuItem>
    </ContextMenu>
</Window.ContextMenu>

public class SortedCollectionViewSource : IValueConverter
{
    public string Property { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var cvs = new CollectionViewSource() { Source = value };
        cvs.SortDescriptions.Add(new SortDescription(Property, ListSortDirection.Ascending));

        return cvs.View;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

pus*_*raj 0

正如错误所示,CollectionViewSource这不是一个FrameworkElement元素,因此绑定将无法解析属性值。

作为解决方案,您可以在视图模型中拥有相同的只读属性并将其绑定到HierarchicalDataTemplate.ItemsSource

例如

    public CollectionViewSource MyCollectionView
    {
        get { return new CollectionViewSource() { Source = Children }; }
    }
Run Code Online (Sandbox Code Playgroud)

并将其绑定为

    <HierarchicalDataTemplate DataType="{x:Type l:CommandGroup}"
                              ItemsSource="{Binding MyCollectionView}">
Run Code Online (Sandbox Code Playgroud)

CollectionViewSource 是 xaml 通常可以绑定到静态/动态资源或静态属性,其他绑定始终存在问题,因为 CollectionViewSource 不传递 DataContext

作为尝试,您可以尝试,但不确定是否有效

<HierarchicalDataTemplate x:name="hTemplate" DataType="{x:Type l:CommandGroup}">
    <HierarchicalDataTemplate.ItemsSource>
        <CollectionViewSource Source="{Binding DataContext.Children,ElementName=hTemplate}" />
Run Code Online (Sandbox Code Playgroud)

如上所述抛出异常尝试这个,如果 CollectionViewSource 能够解析正确的源集合,这可能会起作用

<HierarchicalDataTemplate x:name="hTemplate" DataType="{x:Type l:CommandGroup}">
    <HierarchicalDataTemplate.ItemsSource>
        <Binding>
            <Binding.Source>
                <CollectionViewSource Source="{Binding DataContext.Children,ElementName=hTemplate}" />
Run Code Online (Sandbox Code Playgroud)