Mysql
 sql >> Datenbank >  >> RDS >> Mysql

wie bindet man dynamisches json in treeview wpf

Sie können dies mit Json.NET tun Rahmen. Json.NET hat eine statische Methode JToken.Parse() (was einen ähnlichen Zweck hat wie XDocument.Parse() ) und kann einen gültigen JSON-String in eine Hierarchie von Newtonsoft.Json.Linq.JToken Objekte. Diese Hierarchie kann in einen WPF-Baumansicht Steuerung mit DataTemplate und HierarchicalDataTemplate um Daten aus allen möglichen Unterklassen von JToken zu formatieren und durch ihre Kinder iterieren.

Das konkrete Json.NET JToken Klassen, für die Vorlagen benötigt werden, sind:

Um eine Hierarchie dieser Klassen in einen Baum zu binden, benötigen Sie zunächst einen Konverter zum Konvertieren von JToken.Children() Methode in eine Eigenschaft:

// 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.");
    }
}

Danach ist ein extrem einfaches XAML-Markup, das diese Hierarchie in einer Baumstruktur anzeigen kann, wie folgt:

<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>

Wenn Ihr Benutzer dann die anzuzeigenden JSON-Daten auswählt, können Sie Folgendes tun:

        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;

Und das Ergebnis sieht so aus:

Für Beispiel-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"" }
        ]
}

Natürlich könnte die Benutzeroberfläche schöner gestaltet werden, z.B. indem Sie den Wert für JProperty platzieren Token mit nur einem einzigen JValue Kind in der gleichen Reihe. Dies sollte Ihnen jedoch eine Vorstellung davon geben, wie die Bindung durchgeführt wird.

Dieser Ansatz bindet JSON direkt an den Baum. Wenn Sie nach vollständiger Bearbeitungsfunktionalität suchen, einschließlich Hinzufügen, Entfernen und Umbenennen von Knoten, möchten Sie vielleicht zu einem "Model-View-ViewModel"-Methodik in dem der JToken Hierarchie wird zum Modell und ein leichtgewichtiges Ansichtsmodell verarbeitet Änderungen und Benachrichtigungen.