【问题标题】:How to bind two different collection at one TreeView branch如何在一个 TreeView 分支上绑定两个不同的集合
【发布时间】:2019-06-21 12:20:55
【问题描述】:

我正在编写一个基于 MVVM 模式的 WpfCustomControlLibrary。我有一个 View 包含必须处理扩展模型的 TreeView 对象。

型号:

    public class TreeBranchesView
    {
        public ObservableCollection<DiscountGroup> DiscoutGroups { get; set; }
    }
public class DiscountGroup : ViewModelBase
{
    public int ID { get; set; }
    public string GroupName { get; set; }
    public decimal DefaultValue { get; set; }
    private bool _isCheckedInMenu;
    public bool IsCheckedInMenu
    {
        get { return _isCheckedInMenu; }
        set
        {
            _isCheckedInMenu = value;
            OnPropertyChanged("IsCheckedInMenu");
        }
    }

    public ObservableCollection<SubGroup> SubGroups { get; set; }
    public ObservableCollection<ArticleGroup> ArticleGroup { get; set; }
}

public class SubGroup : ViewModelBase
{
    public int ID { get; set; }
    public int SubGroupParent { get; set; }
    public string Name { get; set; }
    public decimal DefaultValue { get; set; }
    public ObservableCollection<ArticleGroup> ArticleGroup { get; set; }
}

 public class ArticleGroup
{
    public int ArticleID { get; set; }
    public int DiscountGroup { get; set; }
    public int SubGroup { get; set; }
}

我的主要目标是实现以下情况:

-DiscountGroup
--ArticleGroup
--ArticleGroup
-DiscountGroup
--ArticleGroup
--ArticleGroup
--SubGroup
--SubGroup
--SubGroup
---ArticleGroup
---ArticleGroup
-DiscountGroup
-DiscountGroup
--SubGroup

ArticleGroup 和 SubGroups 可以位于同一级别。实际上我的 xaml 看起来像:

<GroupBox Grid.Column="0" Grid.Row="0" Header="MainTree">
     <StackPanel Orientation="Horizontal">
          <TreeView x:Name="MainTreeView" Grid.Column="0" Grid.Row="0" ItemTemplate="{StaticResource level1}" 
           ItemsSource="{Binding TreeBranches}" />
      </StackPanel>
</GroupBox>

所有模板都存储在 windows.resources 下

<Window.Resources>
        <HierarchicalDataTemplate x:Key="level2" ItemsSource="{Binding ArticleGroup}" >
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </HierarchicalDataTemplate> 
        <HierarchicalDataTemplate x:Key="level1" ItemsSource="{Binding SubGroups}" ItemTemplate="{StaticResource level2}" >
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding GroupName}" />
                </StackPanel.ContextMenu>
            </StackPanel>
        </HierarchicalDataTemplate>
</Window.Resources>

我有以下问题 - TreeView 必须在同一级别显示两个不同的集合,而上面的代码 不允许这样做,此时它只处理一个。重要的是,这些集合的类型不同。

【问题讨论】:

  • 那么...您的实际问题是什么?您发布了代码(一个不完整的代码示例)。但是该代码有什么作用?这与您希望代码执行的操作有何不同?您具体遇到了什么问题?请改进问题,使其包含一个可靠地重现问题的良好minimal reproducible example
  • 我已经编辑了问题,希望我的问题现在很清楚。

标签: c# wpf treeview


【解决方案1】:

一种解决方案是为将放置在树中的项目创建一个基类,比如说 TreeNode。这个基类有这个接口:

public interface ITreeNode
{
    ObservableCollection<ITreeNode> Children { get; set; }
    string Name { get; set; }
    ITreeNode Parent { get; set; }
    void AddChild(ITreeNode child);
    void RemoveChild(ITreeNode child);
}

使需要出现在树上的类继承自TreeNode类:

public class DiscountGroup: TreeNode{};
public class SubGroup: TreeNode {}
public class ArticleGroup: TreeNode{}

然后为你的树定义一个根,例如:

Root = new TreeNode() {Name="Root"};

添加一些分支

var dg1 = new DiscountedGroup(){Name = "DG1"}; 
var dg1 = new DiscountedGroup(){Name = "DG1"}; 
Root.AddChild(dg1);
Root.AddChild(dg2};

给分支添加一些子节点

dg1.AddChild(new ArticleGroup());
dg1.AddChild(new SubGroup());
dg2.AddChild(new ArticleGroup());
dg2.Add(new SubGroup());

您可以添加任意数量的图层。然后,在 Xaml 中,将 root.Children 绑定到您的 TreeView.TreeViewItem.ItemsSource。

确保在 Xaml=>TreeViewItem.Resources 中为具有子对象(或仅使用 DataTemplate)的对象(或类)定义了 HierarchicalDataTemplate,并使用 TreeViewItem.ItemTemplateSelector 为每个类检测正确的数据模板。

里面有更多的细节,我试着解释一下。

【讨论】:

  • 谢谢,创建通用集合的好主意。
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 2012-08-24
  • 2019-08-15
  • 2015-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多