如何将动态json绑定到treeview wpf
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23812357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to bind dynamic json into treeview wpf
提问by user2591607
I get JSON as follow:
我得到 JSON 如下:
explain format = json select...
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
文本根据运算符选择的类型而不同。如何在 treeView 中绑定动态 JSON 或在 wpf 中绑定 UML。谢谢你的建议
回答by dbc
You can do this with the Json.NETframework. 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.JTokenobjects. This hierarchy can be bound into a WPF TreeViewcontrol using DataTemplateand HierarchicalDataTemplateto format data from all possible subclasses of JTokenand iterate through their children.
您可以使用Json.NET框架执行此操作。Json.NET 有一个静态方法JToken.Parse()(其目的类似于XDocument.Parse())并且可以将有效的 JSON 字符串转换为Newtonsoft.Json.Linq.JToken对象的层次结构。此层次结构可以绑定到WPF TreeView控件中,使用DataTemplate和HierarchicalDataTemplate格式化来自所有可能子类的数据JToken并遍历其子类。
The concrete Json.NET JTokenclasses for which templates are required are:
JToken需要模板的具体 Json.NET类是:
In order to bind a hierarchy of these classes into a tree, you first need a converterto convert the JToken.Children()method into a property:
为了将这些类的层次结构绑定到树中,首先需要一个转换器将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.");
}
}
Having done this, an extremely simple XAML markup that can display this hierarchy in a tree is:
完成此操作后,可以在树中显示此层次结构的极其简单的 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>
Then, when your user selects JSON data to view, you can do:
然后,当您的用户选择要查看的 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;
And the result looks like:
结果如下:


For the sample JSON:
对于示例 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"" }
]
}
Of course, the user interface could be made more beautiful, e.g. by placing the value for JPropertytokens with only a single JValuechild on the same row. However, this should give you an idea of how to do the binding.
当然,用户界面可以做得更漂亮,例如通过将JProperty只有一个JValue子代的令牌的值放在同一行上。但是,这应该让您了解如何进行绑定。
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" methodologyin which the JTokenhierarchy becomes the model and a lightweight view model handles modifications and notifications.
这种方法直接将 JSON 绑定到树。如果您正在寻找完整的编辑功能,包括添加、删除和重命名节点,您可能希望切换到“模型-视图-视图模型”方法,其中JToken层次结构成为模型,而轻量级视图模型处理修改和通知。
回答by rzr
Based on dbc's answer above I went ahead and created a WPF JSON Viewer user control that should be easily integratable into any WPF project
根据上面 dbc 的回答,我继续创建了一个 WPF JSON 查看器用户控件,它应该可以轻松集成到任何 WPF 项目中


https://bitbucket.org/rasmuszimmer/wpf-jsonviewer-usercontrol
https://bitbucket.org/rasmuszimmer/wpf-jsonviewer-usercontrol
The project is a wpf solution demonstrating its use.
该项目是一个演示其使用的 wpf 解决方案。
Go ahead and do with it whatever you want!
来吧,随心所欲地做吧!

