Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

como vincular o json dinâmico ao wpf do treeview


Você pode fazer isso com o Json.NET estrutura. Json.NET tem um método estático JToken.Parse() (que é semelhante em propósito a XDocument.Parse() ) e pode transformar uma string JSON válida em uma hierarquia de Newtonsoft.Json.Linq.JToken objetos. Essa hierarquia pode ser vinculada a um WPF TreeView controle usando DataTemplate e HierarchicalDataTemplate para formatar dados de todas as subclasses possíveis de JToken e iterar através de seus filhos.

O concreto Json.NET JToken classes para as quais os modelos são necessários são:

Para vincular uma hierarquia dessas classes em uma árvore, primeiro você precisa de um conversor para converter o JToken.Children() método em uma propriedade:
// 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.");
    }
}

Feito isso, uma marcação XAML extremamente simples que pode exibir essa hierarquia em uma árvore é:
<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>

Então, quando seu usuário selecionar dados JSON para visualizar, você poderá fazer:
        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;

E o resultado fica assim:



Para o JSON de amostra :
{
    ""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"" }
        ]
}

Claro, a interface do usuário pode ser mais bonita, por exemplo. colocando o valor para JProperty tokens com apenas um único JValue criança na mesma fila. No entanto, isso deve lhe dar uma idéia de como fazer a ligação.

Essa abordagem vincula o JSON à árvore diretamente. Se você estiver procurando por uma funcionalidade de edição completa, incluindo adicionar, remover e renomear nós, convém mudar para um Metodologia "Model-View-ViewModel" em que o JToken hierarquia se torna o modelo e um modelo de exibição leve lida com modificações e notificações.