c# - 在 propertygrid 中填充 JSON

标签 c# .net json.net propertygrid

这是我的 JSON 文件:

{
"properties": [
    {
        "name": "Text",
        "value": "",
        "default": "",
        "type": "string",
        "desc": "The text associated with the control."
    },
    {
        "name": "Items",
        "default": "item1",
        "items": ["item1","item2","item3"],
        "type": "list",
        "desc": "List of items."
    },
    {
        "name": "Pages",
        "type": "collection",
        "desc": "List of items.",
        "properties": [
              {
                  "name": "Text",
                  "value": "",
                  "default": "",
                  "type": "string",
                  "desc": "The page text."
              }            
        ],
        "items": [
              {
                  "Text": "page1"
              },
              {
                  "Text": "page2"
              }
        ]
    }
]
}

基于 JSON 文件(使用 JSON.net)动态填充属性网格的最佳方法是什么?

我将使用许多这样的文件,因此属性网格将相应地更改,我想这样做,而不是创建 C# 类。

谢谢

最佳答案

你可以做的是使用 custom type descripto r,就像我在这里演示的那样。这是它在标准 winform 中的样子:

enter image description here

  ...
  propertyGrid1.SelectedObject = new JTypeDescriptor(JObject.Parse(File.ReadAllText("test.json")));
  ...

  public class JTypeDescriptor : ICustomTypeDescriptor
  {
      public JTypeDescriptor(JObject jobject)
      {
          if (jobject == null)
              throw new ArgumentNullException("jobject");

          JObject = jobject;
      }

      // NOTE: the property grid needs at least one r/w property otherwise it will not show properly in collection editors...
      public JObject JObject { get; set; }

      public override string ToString()
      {
          // we display this object's serialized json as the display name, for example
          return JObject.ToString(Formatting.None);
      }

      PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
      {
          // browse the JObject and build a list of pseudo-properties
          List<PropertyDescriptor> props = new List<PropertyDescriptor>();
          foreach (var kv in JObject)
          {
              props.Add(new Prop(kv.Key, kv.Value, null));
          }
          return new PropertyDescriptorCollection(props.ToArray());
      }

      AttributeCollection ICustomTypeDescriptor.GetAttributes()
      {
          return null;
      }

      string ICustomTypeDescriptor.GetClassName()
      {
          return null;
      }

      string ICustomTypeDescriptor.GetComponentName()
      {
          return null;
      }

      TypeConverter ICustomTypeDescriptor.GetConverter()
      {
          return null;
      }

      EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
      {
          throw new NotImplementedException();
      }

      PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
      {
          return null;
      }

      object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
      {
          return null;
      }

      EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
      {
          throw new NotImplementedException();
      }

      EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
      {
          throw new NotImplementedException();
      }

      PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
      {
          return ((ICustomTypeDescriptor)this).GetProperties(null);
      }

      object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
      {
          return this;
      }

      // represents one dynamic pseudo-property
      private class Prop : PropertyDescriptor
      {
          private Type _type;
          private object _value;

          public Prop(string name, object value, Attribute[] attrs)
              : base(name, attrs)
          {
              _value = ComputeValue(value);
              _type = _value == null ? typeof(object) : _value.GetType();
          }

          private static object ComputeValue(object value)
          {
              if (value == null)
                  return null;

              JArray array = value as JArray;
              if (array != null)
              {
                  // we use the arraylist because that's all the property grid needs...
                  ArrayList list = new ArrayList();
                  for (int i = 0; i < array.Count; i++)
                  {
                      JObject subo = array[i] as JObject;
                      if (subo != null)
                      {
                          JTypeDescriptor td = new JTypeDescriptor(subo);
                          list.Add(td);
                      }
                      else
                      {
                          JValue jv = array[i] as JValue;
                          if (jv != null)
                          {
                              list.Add(jv.Value);
                          }
                          else
                          {
                              // etc.
                          }
                      }
                  }
                  // we don't support adding things
                  return ArrayList.ReadOnly(list);
              }
              else
              {
                  // etc.
              }
              return value;
          }

          public override bool CanResetValue(object component)
          {
              return false;
          }

          public override Type ComponentType
          {
              get { return typeof(object); }
          }

          public override object GetValue(object component)
          {
              return _value;
          }

          public override bool IsReadOnly
          {
              get { return false; }
          }

          public override Type PropertyType
          {
              get { return _type; }
          }

          public override void ResetValue(object component)
          {
          }

          public override void SetValue(object component, object value)
          {
              _value = value;
          }

          public override bool ShouldSerializeValue(object component)
          {
              return false;
          }
      }
  }

PS:我对 JSON.Net 不是很熟悉,它似乎有一些 JPropertyDescriptor 但我似乎不太适合属性网格。

关于c# - 在 propertygrid 中填充 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25208257/

相关文章:

.net - 使用 REGEX 查找 HTML ListItem (.NET) 的内容

asp.net-mvc - ASP.NET MVC Json DateTime序列化转换为UTC

c# - 使用 json 从字符串反序列化对象之后。您如何知道结果空值之间的差异?

c# - 为什么在 c# 中通过启动进程运行 powershell 时不导入 powershell 模块?

c# - 从 VS2017 附加到 docker 内正在运行的进程

.net - 团队基础服务器 : Cloning a Collection's Project into a new Collection

c# - JToken : Get raw/original JSON value

c# - Ravendb mapreduce 按多个字段分组

c# - 如何在上下文绑定(bind)对象中链接消息接收器(面向方面​​的编程)

c# - Winforms - 引用可更新的配置文件