Valhalla Legends Forums Archive | .NET Platform | PropertyGrid + Reflection.

AuthorMessageTime
K
If you haven't used it before, the .NET Property Grid is a wonderful tool. Write a class, add some attributes, and bind the PropertyGrid to your object. voila:

[img]http://www.darkvariant.com/dubbs/pg/pg_1.png[/img]
[img]http://www.darkvariant.com/dubbs/pg/pg_2.png[/img]
[img]http://www.darkvariant.com/dubbs/pg/pg_3.png[/img]
July 18, 2004, 7:24 PM
peofeoknight
ooo sexy. I do not use vb.net for executable ap programming though :x
July 18, 2004, 7:33 PM
Myndfyr
[quote author=K link=board=37;threadid=7757;start=0#msg71181 date=1090178685]
If you haven't used it before, the .NET Property Grid is a wonderful tool. Write a class, add some attributes, and bind the PropertyGrid to your object. voila:

[img]http://www.darkvariant.com/dubbs/pg/pg_1.png[/img]
[/quote]

That was one of the things I was having trouble with -- how do you get non-enumeration values inside of a field? Or any other selector (like a CSS designer you see in Visual Studio) on a property?
July 19, 2004, 8:10 PM
K
Here's the code for the little drop-down server list:

[code]
// Settings class
// ...
[
Category("Connection"),
// the following line is required for the drop down functionality
TypeConverter(typeof(ServerList)),
/* more attributes... */
DefaultValue("useast.battle.net"),
Description("Enter the hostname or IP address of the server you would like to connect to, or select one from the drop down box.")
]
public string Server
{
   get { return _Server;}
   set { _Server = value; }
}
[/code]


and here is the ServerList class:

[code]
using System;
using System.ComponentModel;

// since the choices are strings, I derived from the StringConverter.
public class ServerList : StringConverter
{
// made static. Good idea.
   protected static string[] _servers = new string[]
   {
      "useast.battle.net",
      "uswest.battle.net",
      "europe.battle.net",
      "asia.battle.net"
      /* etc */
   };

   // simply return your wrapped array
   public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
   {
      return new StandardValuesCollection(_servers);
   }

   // return false: combo box (can enter own value)
   // return true: listbox (cannot enter own value)
   public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
   {
      return false;
   }

   public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
   {
      return true;
   }
}
[/code]


if you want to be able to show a custom string representation of a custom contained class (as well as edit its properties) like so:

[img]http://www.darkvariant.com/dubbs/pg/pg_4.png[/img]

you need to:
1) give the contained class the [TypeConverter(typeof(ExpandableObjectConverter))] attribute
--(no custom string representation or setting properties by modifying the custom string)

or
2) create a class that inherits ExpandableObjectConverter like so:

[code]
public class KarmaUserConverter : ExpandableObjectConverter
{
   public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
   {
      if (destinationType == typeof(KarmaUser))
         return true;

      return base.CanConvertTo(context, destinationType);
   }

   public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
   {
      if (destinationType == typeof(System.String) &&
         value is KarmaUser)
      {
         KarmaUser ku = (KarmaUser)value;

         return ku.Name + (ku.Admin ? " (admin)" : "");
      }
      return base.ConvertTo(context, culture, value, destinationType);
   }
}
[/code]

(the above example does not parse the custom string if it's changed. you need to implement ConvertFrom() and CanConvertFrom() if you want to do that.)
July 20, 2004, 2:03 AM
Myndfyr
[quote author=K link=board=37;threadid=7757;start=0#msg71411 date=1090289039]
[code]
   protected string[] _servers = new string[]
   {
      "useast.battle.net",
      "uswest.battle.net",
      "europe.battle.net",
      "asia.battle.net"
      /* etc */
   };
[/code]
[/quote]

Thank you much. :)

Here's a thought I had: would it be possible to make this static?

[code]
protected static string[] _servers = new string[]
{
"useast.battle.net",
"uswest.battle.net",
"europe.battle.net",
"asia.battle.net"
/* etc */
};
[/code]

That way there is only one reference to the array versus multiple references to the array?

Just a thought, thanks for the info. :)
July 20, 2004, 2:09 AM
K
As a side note, my last screen shot is really cool. It lets the user load any of the .xml configs generated by my bot or plugins, then finds the assembly that that settings class is declared in, finds the settings class and insantiates it through reflection to load / display / save the settings.

For example, in the screen shot, I chose karma_config.xml (settings for the Karma plugin), the application found the PlugDev.KarmaSettings class in Karma.dll and loaded the assembly to parse the xml file.
fun!
July 20, 2004, 2:16 AM

Search