TreeView: привязка к иерархическим данным - PullRequest
0 голосов
/ 07 июня 2019

Я храню древовидные данные в Dictionary, объявленном как:

 Dictionary<string, object>

string является меткой, а object может быть одним из следующих:

  1. A string
  2. An int
  3. A вложенный Dictionary<string, object>

Я пытаюсь заставить это отображаться в TreeView с этим XAML:

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

Это работает для верхнего уровня, но добавление еще одного уровня выглядит следующим образом:

enter image description here

С этими данными:

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

Итак, он работает, когда дочерний объект является string или int, но когда это Dictionary, он просто преобразует его в строку и не обрабатывает его рекурсивно.

Как я могу получить эти данные для отображения?

Edit: Код для построения дерева:

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;

1 Ответ

0 голосов
/ 21 июня 2019

Вы не можете сделать это только в 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"/>

Вот мой результат с вашими данными

* +1012 *enter image description here
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...