【问题标题】:Design-time treeview binding with CollectionViewSources groups and HierarchicalDataTemplate与 CollectionViewSources 组和 HierarchicalDataTemplate 的设计时树视图绑定
【发布时间】:2016-08-08 16:37:26
【问题描述】:

我想在设计时让示例数据出现在我的 Treeview 中。我的 Treeview 包含嵌套的 Treeviews 和 CollectionViewSources。

我想了解如何显示嵌套的树视图(当前仅显示 3 级节点中的第一个)。

关于树形视图

这是我目前所知道的:

我的树视图包含分层数据(对象状态(例如“Ready”)> 日期(例如“8/8/16”)> 名称(例如“Apples”),但我只能得到一个。

Treeview 支持:

  • ObjectTreeviewViewModel(一个 ObservableCollection)
  • CollectionViewSource 按 StateDisplay 分组(+排序)
  • 另一个按 Ob​​jectDateDisplay 分组的 CollectionViewSource

当前状态

ObjectTreeview 在设计时只显示一级节点,而我期望有 3 级节点。

我的堆栈

我正在使用 Visual Studio 2015 在 .net 4.5 上构建 WPF 应用程序。

代码

XAML

    <UserControl x:Class="myproject.app.views.MainWindow.ObjectTreeview"
                             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                             mc:Ignorable="d" 
                             d:DesignHeight="300" d:DesignWidth="300" 
                             DataContext="{Binding RelativeSource={RelativeSource Self}}"
                             >

            <UserControl.Resources>

                    <ResourceDictionary>
                            <ResourceDictionary.MergedDictionaries>
                                    <ResourceDictionary Source="../../resources/MainWindow/ObjectTreeviewResources.xaml"></ResourceDictionary>
                            </ResourceDictionary.MergedDictionaries>
                    </ResourceDictionary>

            </UserControl.Resources>

            <TreeView x:Name="Treeview" 
                                        ItemsSource="{Binding Source={StaticResource ObjectStateCollectionViewSource}, Path=Groups}"
                                        ItemTemplate="{Binding Source={StaticResource ObjectStateTemplate}}">
            </TreeView>

    </UserControl>

XAML 资源

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                            xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
                                            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                                            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                                            xmlns:pf="clr-namespace:System.ComponentModel;assembly=PresentationFramework"
                                            xmlns:mainWindow="clr-namespace:myproject.app.viewmodels.MainWindow"
                                            mc:Ignorable="d">

            <!-- I.e. Level-3 Node (i.e. Leaf nodes) -->
            <DataTemplate x:Key="ObjectTreeviewNode">
                    <TextBlock Text="{Binding ObjectNameDisplay}"/>
            </DataTemplate>


            <!-- Initial Grouping: Group by object states -->
            <CollectionViewSource x:Key="ObjectStateCollectionViewSource" 
                                                        Source="{Binding Path=ObjectTreeviewViewModel.TreeviewCollection}"
                                                        d:DesignSource="{d:DesignData Source=ObjectTreeviewDesignTimeData.xaml}"
                                                        >
                    <CollectionViewSource.GroupDescriptions>
                            <PropertyGroupDescription PropertyName="StateDisplay"/>
                    </CollectionViewSource.GroupDescriptions>
                    <CollectionViewSource.SortDescriptions>
                            <componentModel:SortDescription PropertyName="StateEnum" />
                            <componentModel:SortDescription PropertyName="ObjectDate" />
                            <componentModel:SortDescription PropertyName="ObjectNameDisplay" />
                    </CollectionViewSource.SortDescriptions>
            </CollectionViewSource>

            <!-- I.e. Level-2 Node (i.e. mid-nodes) -->
            <HierarchicalDataTemplate x:Key="ObjectDateTemplate">
                    <TreeView BorderThickness="0">
                            <TreeViewItem Header="{Binding Path=Name}" 
                                                        ItemsSource="{Binding Path=Items}"
                                                        d:DataContext="{Binding Path=Items}"
                                                        ItemTemplate="{StaticResource ResourceKey=ObjectTreeviewNode}"
                                                        IsExpanded="True"/>
                    </TreeView>
            </HierarchicalDataTemplate>

            <!-- I.e. Level-1 Node (i.e. Root nodes) -->
            <HierarchicalDataTemplate x:Key="ObjectStateTemplate" >
                    <TreeView BorderThickness="0">

                            <TreeView.Resources>

                                    <!-- Sub-grouping: Group by object dates (This needs to be nested in this Treeview.Resources) -->
                                    <CollectionViewSource x:Key="ObjectDateCollectionViewSource"
                                                                                Source="{Binding Path=Items}"
                                                                                d:DesignSource="{Binding Path=Items}"
                                                                                > 

                                            <CollectionViewSource.GroupDescriptions>
                                                    <PropertyGroupDescription PropertyName="ObjectDateDisplay"/>
                                            </CollectionViewSource.GroupDescriptions>

                                    </CollectionViewSource>

                                    <!-- [This and all children] Hide the light-grey inactive background -->
                                    <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Transparent" />

                            </TreeView.Resources>

                            <TreeViewItem Header="{Binding Path=Name}" 
                                                        ItemsSource="{Binding Source={StaticResource ObjectDateCollectionViewSource}, Path=Groups}"
                                                        ItemTemplate="{StaticResource ObjectDateTemplate}"
                                                        IsExpanded="True"/>

                    </TreeView>
            </HierarchicalDataTemplate>
    </ResourceDictionary>

代码隐藏

    using System.Windows.Controls;
    using myproject.app.viewmodels.MainWindow;
    using myproject.lib.enumerations;

    namespace myproject.app.views.MainWindow
    {
            /// <summary>
            /// Interaction logic for ObjectTreeview.xaml
            /// </summary>
            public partial class ObjectTreeview : UserControl
            {
                    public ObjectTreeviewViewModel ObjectTreeviewViewModel { get; private set; } = new ObjectTreeviewViewModel(); // this is a ObservableCollection<ObjectViewModel>

                    public ObjectTreeview()
                    {
                            InitializeComponent();
                    }

                    /// <summary>
                    ///     Load object for an objectStateGroup (a set of ObjectStates) into the collection that backs the treeview.
                    /// </summary>
                    /// <param name="objectStateGroup">The objectStateGroupsEnum to load.</param>
                    public void LoadObjectStateGroup(objectStateGroupsEnum objectStateGroup)
                    {
                            ObjectTreeviewViewModel.LoadobjectStateGroup(objectStateGroup);
                    }
            }
    }

【问题讨论】:

    标签: c# .net wpf visual-studio xaml


    【解决方案1】:

    我找到了解决问题的方法。

    问题

    问题出在内部 CollectionViewSource(控制 3 个节点中间的那个)。只有外部的 CollectionViewSource 显示了它的节点。

    设计时绑定不能使用与运行时相同的Path=Items

    <CollectionViewSource x:Key="ObjectDateCollectionViewSource"
                          Source="{Binding Path=Items}"
                          d:DesignSource="{Binding Path=Items}"> 
    
                    <CollectionViewSource.GroupDescriptions>
                                    <PropertyGroupDescription PropertyName="ObjectDateDisplay"/>
                    </CollectionViewSource.GroupDescriptions>
    
    </CollectionViewSource>
    

    解决方案

    更新 d:DesignSource 以使用 Source=ObjectTreeviewDesignTimeData.xaml 从 XAML 示例文件(我们在上面使用的相同)加载。

        <CollectionViewSource x:Key="ObjectDateCollectionViewSource"
                              Source="{Binding Path=Items}"
                              d:DesignSource="{d:DesignData Source=ObjectTreeviewDesignTimeData.xaml}"> 
    
                <CollectionViewSource.GroupDescriptions>
                        <PropertyGroupDescription PropertyName="ObjectDateDisplay"/>
                </CollectionViewSource.GroupDescriptions>
    
        </CollectionViewSource>
    

    设置 d:DesignSource 并重新构建后,3 级节点开始在设计时出现。我确认设计时绑定的问题在于内部 CollectionViewSource。

    足够的解决方法

    通过绑定到外部和内部CollectionViewSources中的同一个字典,会产生冗余数据。 (对于每个子树视图,字典会加载多次。)但是,这没关系,因为我处于设计器模式,我只需要占位符数据。

    更好的解决方案是找到一种方法让内部 CVS d:DesignerSource="{BETTER_SOLUTION_HERE}" 部分使用与外部 CVS 相同的集合来工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-05
      • 1970-01-01
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-13
      相关资源
      最近更新 更多