如何将动态json绑定到treeview wpf中 [英] how to bind dynamic json into treeview wpf

查看:273
本文介绍了如何将动态json绑定到treeview wpf中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到的JSON如下:

I get JSON as follow:

explain format = json select...

文本根据操作员选择的类型而不同.如何在treeView或wpf中的UML中绑定动态JSON. 寻求建议

Text is different depending on the type of operator select. How to bind dynamic JSON in treeView or maybe UML in wpf. Thx for advice

推荐答案

您可以使用 Json.NET进行此操作框架. Json.NET具有静态方法 JToken.Parse() (类似故意 XDocument.Parse() ),并且可以将有效的JSON字符串转换为 Newtonsoft.Json.Linq.JToken 对象.可以将此层次结构绑定到 WPF TreeView 使用 DataTemplate HierarchicalDataTemplate 来格式化数据JToken的所有可能子类,并遍历其子级.

You can do this with the Json.NET framework. Json.NET has a static method JToken.Parse() (which is similar in purpose to XDocument.Parse()) and can turn a valid JSON string into a hierarchy of Newtonsoft.Json.Linq.JToken objects. This hierarchy can be bound into a WPF TreeView control using DataTemplate and HierarchicalDataTemplate to format data from all possible subclasses of JToken and iterate through their children.

需要模板的具体Json.NET JToken类是:

The concrete Json.NET JToken classes for which templates are required are:

  • JValue
  • JObject
  • JArray
  • JProperty
  • JConstructor
  • JRaw

要将这些类的层次结构绑定到树中,首先需要 JToken.Children() 将方法转换为属性:

In order to bind a hierarchy of these classes into a tree, you first need a converter to convert the JToken.Children() method into a property:

// Respectfully adapted from https://stackoverflow.com/questions/502250/bind-to-a-method-in-wpf/844946#844946

public sealed class MethodToValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var methodName = parameter as string;
        if (value == null || methodName == null)
            return null;
        var methodInfo = value.GetType().GetMethod(methodName, new Type[0]);
        if (methodInfo == null)
            return null;
        return methodInfo.Invoke(value, new object[0]);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException(GetType().Name + " can only be used for one way conversion.");
    }
}

完成此操作后,可以在树中显示此层次结构的极其简单的XAML标记是:

Having done this, an extremely simple XAML markup that can display this hierarchy in a tree is:

<Window x:Class="WpfJsonTreeViewNew.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:w="clr-namespace:WpfJsonTreeViewNew"
    xmlns:json ="clr-namespace:Newtonsoft.Json;assembly=Newtonsoft.Json"
    xmlns:jlinq ="clr-namespace:Newtonsoft.Json.Linq;assembly=Newtonsoft.Json"
    Title="Window1" Height="1000" Width="600">
    <Window.Resources>
        <w:MethodToValueConverter x:Key="MethodToValueConverter"/>
        <HierarchicalDataTemplate DataType="{x:Type jlinq:JArray}" ItemsSource="{Binding Converter={StaticResource MethodToValueConverter}, ConverterParameter='Children'}">
            <TextBlock Text="Array">
            </TextBlock>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="{x:Type jlinq:JProperty}" ItemsSource="{Binding Converter={StaticResource MethodToValueConverter}, ConverterParameter='Children'}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Property name: "/>
                <TextBlock Text="{Binding Path=Name, Mode=OneWay}"/>
            </StackPanel>
        </HierarchicalDataTemplate>            
        <HierarchicalDataTemplate DataType="{x:Type jlinq:JObject}" ItemsSource="{Binding Converter={StaticResource MethodToValueConverter}, ConverterParameter='Children'}">
            <TextBlock Text="Object">
            </TextBlock>
        </HierarchicalDataTemplate>            
        <HierarchicalDataTemplate DataType="{x:Type jlinq:JConstructor}" ItemsSource="{Binding Converter={StaticResource MethodToValueConverter}, ConverterParameter='Children'}">
            <TextBlock Text="Constructor">
            </TextBlock>
        </HierarchicalDataTemplate>            
        <HierarchicalDataTemplate DataType="{x:Type jlinq:JRaw}" ItemsSource="{Binding Converter={StaticResource MethodToValueConverter}, ConverterParameter='Children'}">
            <TextBlock Text="Raw">
            </TextBlock>
        </HierarchicalDataTemplate>            
        <DataTemplate DataType="{x:Type jlinq:JValue}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Value: "/>
                <TextBox Text="{Binding Path=Value, Mode=TwoWay}"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <TreeView Margin="3" Name="treeView1">
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="IsExpanded" Value="True" />
                </Style>
            </TreeView.ItemContainerStyle>
        </TreeView>
    </Grid>
</Window>

然后,当用户选择要查看的JSON数据时,您可以执行以下操作:

Then, when your user selects JSON data to view, you can do:

        var token = JToken.Parse(jsonString);

        var children = new List<JToken>();
        if (token != null)
        {
            children.Add(token);
        }

        treeView1.ItemsSource = null;
        treeView1.Items.Clear();
        treeView1.ItemsSource = children;

结果如下:

对于示例JSON :

{
    ""id"": ""0001"",
    ""type"": ""donut"",
    ""name"": ""Cake"",
    ""ppu"": 0.55,
    ""batters"":
        {
            ""batter"":
                [
                    { ""id"": ""1001"", ""type"": ""Regular"" },
                    { ""id"": ""1002"", ""type"": ""Chocolate"" },
                    { ""id"": ""1003"", ""type"": ""Blueberry"" },
                    { ""id"": ""1004"", ""type"": ""Devil's Food"" }
                ]
        },
    ""topping"":
        [
            { ""id"": ""5001"", ""type"": ""None"" },
            { ""id"": ""5002"", ""type"": ""Glazed"" },
            { ""id"": ""5005"", ""type"": ""Sugar"" },
            { ""id"": ""5007"", ""type"": ""Powdered Sugar"" },
            { ""id"": ""5006"", ""type"": ""Chocolate with Sprinkles"" },
            { ""id"": ""5003"", ""type"": ""Chocolate"" },
            { ""id"": ""5004"", ""type"": ""Maple"" }
        ]
}

当然,可以使用户界面更加美观,例如通过将JProperty令牌的值放置在同一行中,且只有一个JValue子代.但是,这应该使您了解如何进行绑定.

Of course, the user interface could be made more beautiful, e.g. by placing the value for JProperty tokens with only a single JValue child on the same row. However, this should give you an idea of how to do the binding.

此方法将JSON直接绑定到树.如果您正在寻找包括添加,删除和重命名节点的完整编辑功能,则可能要切换到,其中JToken层次结构成为模型,而轻量级视图模型处理修改和通知.

This approach binds the JSON to the tree directly. If you are looking for full editing functionality including adding, removing and renaming nodes, you may want to switch to a "Model-View-ViewModel" methodology in which the JToken hierarchy becomes the model and a lightweight view model handles modifications and notifications.

这篇关于如何将动态json绑定到treeview wpf中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆