如何在WPF TreeView中显示JSON

时间:2018-03-30 19:17:14

标签: json wpf hierarchicaldatatemplate

我正在阅读JSON,然后在WPF树视图中显示它。

这是代码......

Class MainWindow
Public Sub New()

    InitializeComponent()
    Dim dic = GetThreadedObject(GetJASN())("phases")
    Dim items = dic(0)
    tView.ItemsSource = items

End Sub

Private Function GetJASN() As String
    Dim output As String = My.Computer.FileSystem.ReadAllText(My.Application.Info.DirectoryPath & "\UAL525 Phase of Flight.json")
    Return output
End Function

Private Function GetThreadedObject(JASN As String)
    Dim Js As New JavaScriptSerializer()
    Js.MaxJsonLength = JASN.Length * 2
    Dim j = Js.Deserialize(Of Object)(JASN)
    Return j
End Function
End Class

WPF ......

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <TreeView x:Name="tView">

    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Value}" >
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}" Foreground="Red"/>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
            <TextBlock Text="{Binding Key}"/>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>

</TreeView>
</Grid>

Start Point and End Point

起点和终点(上图)看起来很好(大概是因为它们包含要显示的子元素)。

Phase

但是Phase元素应该只包含一个值。单个字符串,显示“GROUND”。但由于某种原因,它被分解为charArray。并显示在多个元素中,如上所示。

那么解决这个问题的关键是什么?显示字符串的多个数据模板与其他对象不同?

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

以下是Rekshino在Vb。

中提交的代码
<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApp2"
    Title="Window1" Height="300" Width="300">

<Window.Resources>
    <local:ValConv x:Key="valConv"/>
</Window.Resources>
<Grid>
    <TreeView x:Name="tView">

    <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Value, Converter={StaticResource valConv}}" >
                <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}" Foreground="Red"/>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
            <TextBlock Text="{Binding Key}"/>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>

</TreeView>
</Grid>

结束班

hide.bs.modal

答案 1 :(得分:0)

问题是你的XAML只能在字典的值中显示集合,如果有sname,那么它将被视为字符集合。其中一个快速解决方案是创建一个转换器,它将您的字符串转换为字符串集合。

为此你需要一个值转换器(抱歉我用c#编写代码)

string


在资源中实例化此转换器:

public class ValConv : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string str)
        {
            return new List<string> { str };
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}


并使用它:

<Window.Resources>
<local:ValConv x:key="valKonv"/>
</Window.Resources>

答案 2 :(得分:0)

我需要更通用的操作来使用任何JSON。

此代码使用nuget Newtonsoft JSON来完成获取任何原始JSON(无模型)并将其加载到如下所示的TreeView中的魔力:

enter image description here

JSON

string jsonString = @"[{""BatchId"":0,""AccessionChanges"":[{""LabId"":8675309,""InstanceChanges"":[{""Property"":""Note"",""ChangedTo"":""Jabberwocky"",""UniqueId"":null,""SummaryInstance"":null},{""Property"":""Instrument"",""ChangedTo"":""instrumented"",""UniqueId"":null,""SummaryInstance"":null}],""DetailChanges"":[{""Property"":""Comments"",""ChangedTo"":""2nd Comment"",""UniqueId"":null,""SummaryInstance"":null},{""Property"":""CCC"",""ChangedTo"":""XR71"",""UniqueId"":null,""SummaryInstance"":null}]}]}]";

Xaml <TreeView x:Name="tView" />

Codbehind Xaml

InitializeComponent();
try
{
    tView.Items.Add(JSONOperation.Json2Tree(JArray.Parse(jsonString), "Root"));    
}
catch (JsonReaderException jre)
{
    MessageBox.Show($"Invalid Json {jre.Message}");
}

公共静态类JSONOperation

public static TreeViewItem Json2Tree(JToken root, string rootName = "")
{
    var parent = new TreeViewItem() { Header = rootName };

    foreach (JToken obj in root)
        foreach (KeyValuePair<string, JToken> token in (JObject)obj)
            switch (token.Value.Type)
            {
                case JTokenType.Array:
                    var jArray = token.Value as JArray;

                    if (jArray?.Any() ?? false)
                        parent.Items.Add(Json2Tree(token.Value as JArray, token.Key));
                    else
                        parent.Items.Add($"\x22{token.Key}\x22 : [ ]"); // Empty array   
                    break;

                case JTokenType.Object:
                    parent.Items.Add(Json2Tree((JObject)token.Value, token.Key));
                    break;

                default:
                    parent.Items.Add(GetChild(token));
                    break;
            }

    return parent;
}

private static TreeViewItem GetChild(KeyValuePair<string, JToken> token)
{
    var value = token.Value.ToString();
    var outputValue = string.IsNullOrEmpty(value) ? "null" : value;
    return new TreeViewItem() { Header = $" \x22{token.Key}\x22 : \x22{outputValue}\x22" 
}