如何将动态json绑定到treeview wpf

时间:2014-05-22 16:24:22

标签: mysql json wpf treeview

我得到JSON如下:

explain format = json select...

根据操作员选择的类型,文本会有所不同。如何在treeView中绑定动态JSON,或者在wpf中绑定UML。 请求建议

2 个答案:

答案 0 :(得分:31)

您可以使用Json.NET框架执行此操作。 Json.NET有一个静态方法JToken.Parse()(目的与XDocument.Parse()类似),可以将有效的JSON字符串转换为Newtonsoft.Json.Linq.JToken个对象的层次结构。可以使用WPF TreeViewDataTemplate将此层次结构绑定到HierarchicalDataTemplate控件中,以格式化来自JToken的所有可能子类的数据,并遍历其子项。

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

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

// 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标记是:

<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数据时,您可以执行以下操作:

        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;

结果如下:

enter image description here

对于sample 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子项的位置。但是,这应该可以让您了解如何进行绑定。

此方法直接将JSON绑定到树。如果您正在寻找完整的编辑功能,包括添加,删除和重命名节点,您可能希望切换到"Model-View-ViewModel" methodology层次结构成为模型的{{3}},轻量级视图模型处理修改和通知。

答案 1 :(得分:20)

基于dbc上面的回答,我继续创建了一个WPF JSON Viewer用户控件,该控件应该可以轻松集成到任何WPF项目中

Imgur

https://bitbucket.org/rasmuszimmer/wpf-jsonviewer-usercontrol

该项目是一个展示其用途的wpf解决方案。

继续做任何你想做的事!