【问题标题】:Having trouble binding to a treeview in WPF在 WPF 中绑定到树视图时遇到问题
【发布时间】:2015-02-11 23:43:36
【问题描述】:

我正在尝试制作一个表示文件数据的树视图。文件数据具有组织成三个不同部分的数据包:头信息、操作头和操作数据。 Header Info 和 Operation Header 中的数据包是一层深度,而 Operation Data 中的数据包被分组到列表中,所以我认为将其提高一层会更容易组织。这样您就可以弹出打开的数据,查看列表,然后弹出打开的列表以查看单个数据包。

这是我的 xaml:

<TreeView ItemsSource="{Binding TreeViewItems}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding TreeNodes}">
                    <TextBlock Text="{Binding Name}" />

                    <HierarchicalDataTemplate.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                            <TextBlock Text="{Binding Name}" />
                            
                                    <HierarchicalDataTemplate.ItemTemplate>
                                        <HierarchicalDataTemplate>
                                            <TextBlock Text="{Binding DataPackets.ItemName}"/>                                                 
                                        </HierarchicalDataTemplate>
                                    </HierarchicalDataTemplate.ItemTemplate>

                        </HierarchicalDataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>

                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

这是我们尝试绑定到分层数据模板的代码:

                var childData = new Children();

                result.OperationData.ToList().ForEach(x => childData.DataPackets.Add(x));

                
                if (result.HeaderInfo.Any())
                {
                    TreeViewItems.Add(new TreePair() { TreeNodes = result.HeaderInfoProperties.ToList(), Name = "Header Info" });
                }
                TreeViewItems.Add(new TreePair() { TreeNodes = result.OperationHeaderProperties.ToList(), Name = "Operation Header" });
                TreeViewItems.Add(new TreePair() { TreeNodes = result.OperationDataProperties.ToList(), Children = new List<Children> {childData}, Name = "Operation Data" });

public class TreePair
    {
        

        public TreePair()
        {               
            TreeNodes = new List<PropertyInfo>();
            Children = new List<Children>();
        }

        public List<Children> Children { get; set; }

        public List<PropertyInfo> TreeNodes { get; set; }

        public string Name { get; set; }
    }

    public class Children
    {
        public Children()
        {
            DataPackets = new List<DataPacketBase>();
        }

        public string Name { get; set; }

        public List<DataPacketBase> DataPackets { get; set; }
    }

我显示了 Header info 和 operation header 的数据包,以及 Operation data 的列表名称,但没有一个子数据包出现。它们存在于 Children.DataPackets 对象中。

这是在输出窗口中抛出的: BindingExpression 路径错误:在 'object' 上找不到 'Children' 属性

第二个TextBlock是正确的,但是没有找到Children ItemSource,但是列表正在填充项目。

第二层缺少子名属性

【问题讨论】:

    标签: c# wpf xaml data-binding treeview


    【解决方案1】:

    绑定找不到Children,因为它正在PropertyInfo 对象上寻找它。 ChildrenTreeNodes 是树中的兄弟姐妹,两者之间没有子/父关系,因此当 HierarchicalDataTemplate 试图找到属于 PropertyInfo 对象的 Children 对象时,它会被破坏。

    如果您的对象层次结构正确,那么您将需要一个 CompositeCollection,它可以将 TreeNodes 和 Children 对象组合到一个集合中。

        private CompositeCollection _treeNodeChildCollections;
        public CompositeCollection TreeNodeChildCollections
        {
            get
            {
                if (_treeNodeChildCollections == null)
                {
                    _treeNodeChildCollections = new CompositeCollection();
                    var cc1 = new CollectionContainer();
                    cc1.Collection = Children;
                    var cc2 = new CollectionContainer();
                    cc2.Collection = TreeNodes;
    
                    _treeNodeChildCollections.Add(cc1);
                    _treeNodeChildCollections.Add(cc2);
                }
    
                return _treeNodeChildCollections;
            }
        }
    

    然后绑定到 xaml 中的那个。

        <TreeView ItemsSource="{Binding TreeViewItems}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding TreeNodeChildCollections}">
                    <TextBlock Text="{Binding Name}" />
                    <HierarchicalDataTemplate.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding DataPackets}">
                            <TextBlock Text="{Binding Name}"/>
                            <HierarchicalDataTemplate.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding ItemName}"/>
                                </DataTemplate>
                            </HierarchicalDataTemplate.ItemTemplate>
                        </HierarchicalDataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    

    【讨论】:

    • 这差不多了,它显示了所有三个级别,但是第2级字符串“名称丢失”?第一级文本块绑定到名为 Name 的属性,第二级文本块应绑定到另一个名为 name 的属性,第三级应绑定到名为 ItemName 的文本块。第二级项目在树视图中,但名称未显示。
    • 那么哪些项目没有显示他们的Name
    • 我用底部的图像更新了问题,显示缺少第二级字符串名称。我应该是 Children 的 name 属性。
    • 再次更新第二张图片,突出显示树视图中缺少字符串的项目。当我扩展第二级时,它会使用您的答案正确显示。赞成您的回答。
    • 在我看来,绑定到 Children 对象是正确的,因此问题必须专门针对 Name 属性。你能调试并确认Name有值吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 2010-11-03
    相关资源
    最近更新 更多