我得到JSON如下:
explain format = json select...
根据操作员选择的类型,文本会有所不同。如何在treeView中绑定动态JSON,或者在wpf中绑定UML。 请求建议
答案 0 :(得分:31)
您可以使用Json.NET框架执行此操作。 Json.NET有一个静态方法JToken.Parse()
(目的与XDocument.Parse()
类似),可以将有效的JSON字符串转换为Newtonsoft.Json.Linq.JToken
个对象的层次结构。可以使用WPF TreeView和DataTemplate
将此层次结构绑定到HierarchicalDataTemplate
控件中,以格式化来自JToken
的所有可能子类的数据,并遍历其子项。
需要模板的具体Json.NET JToken
类是:
为了将这些类的层次结构绑定到树中,首先需要converter将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层次结构成为模型的{{3}},轻量级视图模型处理修改和通知。
答案 1 :(得分:20)
基于dbc上面的回答,我继续创建了一个WPF JSON Viewer用户控件,该控件应该可以轻松集成到任何WPF项目中
https://bitbucket.org/rasmuszimmer/wpf-jsonviewer-usercontrol
该项目是一个展示其用途的wpf解决方案。
继续做任何你想做的事!