TreeView:绑定到分层数据

TreeView: bind to hierarchical data

我将树状数据存储在 Dictionary 中,声明如下:

 Dictionary<string, object>

string是一个标签,object可以是以下之一:

  1. 一个string
  2. 一个int
  3. 嵌套Dictionary<string, object>

我正在尝试通过 XAML:

将其显示在 TreeView
<TreeView Background="Black" Foreground="Yellow" ItemsSource="{Binding}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Path=Value}">
            <TextBlock Foreground="Red" Text="{Binding Path=Key}" />
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Foreground="LightGreen" Text="{Binding Path=Key}"/>
                        <TextBlock Foreground="White" Text="="/>
                        <TextBlock Foreground="Yellow" Text="{Binding Path=Value}"/>
                    </StackPanel>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

这适用于顶级,但添加另一个级别如下所示:

有了这个数据:

Variable1...
  child1 = "hello"
  child2 = "there"
  child3...
    sub1 = "how"
    sub2 = "are"
    sub3 = "you"
Variable2...
  child1 = "lorem"
  child2 = "ipsum"

所以,当子对象是stringint时,它有效,但是当它是Dictionary时,它只是将它转换为字符串,而不是递归处理它.

如何显示这些数据?

编辑: 构建树的代码:

Dictionary<string, object> data = new Dictionary<string, object>();
Dictionary<string, object> child = new Dictionary<string, object>();
child["child1"] = "hello";
child["child2"] = "there";
Dictionary<string, object> child2 = new Dictionary<string, object>();
child2["sub1"] = "how";
child2["sub2"] = "are";
child2["sub3"] = "you";
child["child3"] = child2;
data["Variable1"] = child;

child = new Dictionary<string, object>();
child["child1"] = "lorem";
child["child2"] = "ipsum";
data["Variable2"] = child;

variablesWindow.DataContext = data;

你不能只在 xaml 中这样做,因为你不知道你的树有多深你必须设置一个 递归方法 来创建你的树.

我背后的代码:

public partial class MainPage : Window
{
    private SolidColorBrush[] treeColors => new[]
    {
        Brushes.Red,
        Brushes.Green,
        Brushes.Yellow,
        Brushes.Purple,
        Brushes.Blue
    };

    public MainPage()
    {
        InitializeComponent();
        Dictionary<string, object> data = new Dictionary<string, object>();
        Dictionary<string, object> child = new Dictionary<string, object>();
        child["child1"] = "hello";
        child["child2"] = "there";
        Dictionary<string, object> child2 = new Dictionary<string, object>();
        child2["sub1"] = "how";
        child2["sub2"] = "are";
        child2["sub3"] = "you";
        child["child3"] = child2;
        data["Variable1"] = child;

        child = new Dictionary<string, object>();
        child["child1"] = "lorem";
        child["child2"] = "ipsum";
        data["Variable2"] = child;

        foreach (var item in data)
        {
            MyTreeView.Items.Add(CreateTreeViewItem(item.Value, item.Key));
        }
    }

    private object CreateTreeViewItem(object obj, string header, int deep = 0)
    {
        // Next color but don't make an out of range
        if (deep > treeColors.Length - 1) deep = treeColors.Length - 1;

        var item = new TreeViewItem()
        {
            Header = header,
            Foreground = treeColors[deep]
        };

        // Create a new tree view item
        if (obj is Dictionary<string, object> dic)
        {
            foreach (var o in dic)
            {
                item.Items.Add(CreateTreeViewItem(o.Value, o.Key, deep + 1));
            }
        }

        // Write the "header = value"
        else
        {
            item.Header = new StackPanel()
            {
                Orientation = Orientation.Horizontal,
                Children =
                {
                    new TextBlock
                    {
                        Text = header,
                        Foreground = treeColors[deep]
                    },
                    new TextBlock
                    {
                        Text = " = ",
                        Foreground = Brushes.White
                    },
                    new TextBlock
                    {
                        Text = obj.ToString(),
                        // Next color but don't make an out of range
                        Foreground = deep == treeColors.Length - 1? treeColors[deep]: treeColors[deep + 1]
                    },
                }
            };
        }

        return item;
    }
}

还有我的小 xaml :

<TreeView x:Name="MyTreeView" Background="Black" Foreground="Yellow"/>

你的数据就是我的结果