See the question and my original answer on StackOverflow

What you could do is use a custom type descriptor, like I demonstrate here. Here is how it looks in a standard 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: I'm not super familiar with JSON.Net, and it seems to have some JPropertyDescriptor but I does not seem really property grid suitable.