【问题标题】:using a CollectionViewSource with HierarchicalDataTemplate使用带有 HierarchicalDataTemplate 的 CollectionViewSource
【发布时间】:2014-09-27 10:44:48
【问题描述】:

您将如何将 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>

我认为我可能能够执行以下操作,但它会破坏后代的显示以及产生以下绑定错误。

<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')

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

 <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();
    }
}

【问题讨论】:

    标签: wpf collectionviewsource hierarchicaldatatemplate


    【解决方案1】:

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

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

    例如

        public CollectionViewSource MyCollectionView
        {
            get { return new CollectionViewSource() { Source = Children }; }
        }
    

    并将其绑定为

        <HierarchicalDataTemplate DataType="{x:Type l:CommandGroup}"
                                  ItemsSource="{Binding MyCollectionView}">
    

    CollectionViewSource 是 xaml 可以正常绑定到静态/动态资源或静态属性,其他绑定总是有问题,因为 CollectionViewSource 不传递 DataContext

    您可以尝试一下,但不确定是否有效

    <HierarchicalDataTemplate x:name="hTemplate" DataType="{x:Type l:CommandGroup}">
        <HierarchicalDataTemplate.ItemsSource>
            <CollectionViewSource Source="{Binding DataContext.Children,ElementName=hTemplate}" />
    

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

    <HierarchicalDataTemplate x:name="hTemplate" DataType="{x:Type l:CommandGroup}">
        <HierarchicalDataTemplate.ItemsSource>
            <Binding>
                <Binding.Source>
                    <CollectionViewSource Source="{Binding DataContext.Children,ElementName=hTemplate}" />
    

    【讨论】:

    • 谢谢,但我正在寻找仅适用于 Xaml 的解决方案。我也尝试了你的最后一个建议,但它引发了类似的错误。 {"'System.Windows.Data.CollectionViewSource' 类型的对象无法转换为 'System.Windows.Data.BindingBase' 类型。"}
    • 尝试更新的方法可能对您有用。顺便说一句,您需要CollectionViewSource 的原因是什么?我们可以尝试解决方法吗?
    • 这会产生同样的错误。正如我在最初的帖子中提到的,CollectionViewSource 是为了启用排序
    • 好吧,我也害怕。你愿意使用依附行为吗?我们可以创建一个附加属性作为解决方法。但是会涉及一些代码,但这可能不会改变您现有的类。就像添加一个新类一样简单。
    • 您使用转换器做得很好。通过附加属性,我们可以使这种行为可附加,实际上除了几行代码之外没有什么区别。我会写一个示例供您比较。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多