sql >> データベース >  >> RDS >> Mysql

動的jsonをtreeviewwpfにバインドする方法

    これは、JSON.NET を使用して実行できます。 フレームワーク。 Json.NETには静的メソッドJToken.Parse() (これは、目的が XDocument.Parse() )有効なJSON文字列を Newtonsoft.Json.Linq.JToken オブジェクト。この階層は、 WPF TreeView DataTemplate および HierarchicalDataTemplate JTokenのすべての可能なサブクラスからのデータをフォーマットします 子供たちを繰り返します。

    具体的なJson.NETJToken テンプレートが必要なクラスは次のとおりです。

    これらのクラスの階層をツリーにバインドするには、最初にコンバーター 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;
    

    結果は次のようになります:

    サンプル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が1つしかないトークン 同じ行の子。ただし、これにより、バインディングを実行する方法がわかります。

    このアプローチでは、JSONをツリーに直接バインドします。ノードの追加、削除、名前の変更など、完全な編集機能をお探しの場合は、"Model-View-ViewModel"方法論 JToken 階層がモデルになり、軽量ビューモデルが変更と通知を処理します。



    1. cordovaを使用してプロジェクトファイルにローカルに保存されているSqliteデータベースファイル[アセットフォルダ]にアクセスして更新する方法

    2. ID値を返すときのExecuteScalarとExecuteNonQuery

    3. #1025-mysqlの名前変更(errno:150)でエラーが発生しました

    4. MySQLでテーブルの名前を変更する方法