如何将动态JSON绑定到treeview wpf中

egdjgwm8  于 2023-01-18  发布在  其他
关注(0)|答案(3)|浏览(407)

我得到JSON如下:

explain format = json select...

文本根据操作符选择的类型而不同。如何在treeView中绑定动态JSON或者在wpf.thx中绑定UML以获得建议

bd1hkmkf

bd1hkmkf1#

您可以使用Json.NET框架完成此操作。Json.NET有一个静态方法JToken.Parse()(其用途类似于XDocument.Parse()),并可以将有效的JSON字符串转换为Newtonsoft.Json.Linq.JToken对象的层次结构。可以使用DataTemplateHierarchicalDataTemplate将此层次结构绑定到WPF TreeView控件中,以格式化来自JToken的所有可能子类的数据并进行迭代他们的孩子。
需要模板的具体Json.NET JToken类包括:

为了将这些类的层次结构绑定到树中,首先需要一个转换器将JToken.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;

结果如下所示:

对于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,其中JToken层次结构成为模型,轻量级视图模型处理修改和通知。

g2ieeal7

g2ieeal72#

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

https://bitbucket.org/rasmuszimmer/wpf-jsonviewer-usercontrol
该项目是一个演示其使用的wpf解决方案。
你想怎么做就怎么做!

yptwkmov

yptwkmov3#

您可以简单地安装nuGet包JSONTreeView并调用函数:

treeView.ProcessJson(string json);

这将是结果:

相关问题