Dynamic parameters dialog (using reflection)

Does anyone know of a good component (C # WinForms) that will allow you to create a form (settings) of a form given a custom class with a bunch of properties? I'm not looking for something shiny, but something just better than a property grid. I can easily take care of the visual part, but I just don't want to waste time doing reflection in order to add and bind controls if they already exist.

I'm sure I've seen a Visual Studio-like form somewhere before that was created dynamically (with some attributes attached to class properties to allow grouping and additional information).

[Edit] For example, I might have a parameter class:

public class Options : SerializableOptions<Options>
{
     [Category("General")]
     [Name("User name")]
     [Description("Some text")]
     public string Username { get; set; }

     [Category("General")]
     [Name("Log in automatically")]
     public bool LogInAutomatically { get; set; }

     [Category("Advanced")]
     // ConnectionType is enum
     public ConnectionType ConnectionType { get; set; }

     // ...
}

      

After submitting it to this form, it will create two panes (General and Advanced), with a CheckBox and TextBox in the first pane and one ComboBox (with all available enumerations) in the second pane.

If there is no such control, what are you guys using? Manually add, fill, format, and bind controls for each option?

+2


source to share


3 answers


I don't know of any controls that will allow you to do this, but it's not hard to do it yourself. The easiest way is to create a dialog wrapper, a custom control that acts as a base class for the "panel" options, one (or more) attributes for managing the name and grouping information, and an interface (which implements user control).

Each of your custom control panels gets from a custom control and overrides some method Initialize()

and Save()

(provided by the custom control). It also provides your attribute (or attributes) which defines the title / grouping information.



In the shell of the dialog, reflect all the public types from your assembly (or all loaded assemblies) that are looking for types that implement your interface. When you find the type, get the attributes to determine where to put them in your group (the tree view is easiest to use), call Activator.CreateInstance

to instantiate the custom control and store it in the Tag

property. When the user clicks on an entry in the group (tree node), get Tag

and set the panel that contains the user control for the object in the property Tag

. Finally, when the user clicks OK in the dialog, scroll through the tree nodes, get the property, Tag

and call the method Save

.

Update: Another option is to use property grid control. It doesn't have a "pretty" user interface, but it is very functional, it already supports grouping by category attribute and provides a lot of flexibility. You can go with a single property grid that displays all options, or go with a "hybrid" approach with a tree view that is grouped by major functionality (plugin, capabilities, etc.), probably based on type. When the user clicks the node button, give the property grid an object instance. The only drawback of this approach is that when changes are made to the values ​​of the property grid, they "live" in the fact that the underlying property changes immediately, which means that the concept of "Cancel" does not exist, except for saving a copy of each value.which can change and do some type of "reset" on its own.

+2


source


I don't know if such a control exists, but writing the required reflection code is really not that hard. For example. something like that:

// the class for which to create an UI
public class MyClass
{
    public string Text { get; set; }
    public int ID { get; set; }
}

      



...

// basic reflection code to build the UI for an object
var obj = new MyClass() { Text="some text", ID=3};

foreach (var pi in obj.GetType().GetProperties())
{
    var name = pi.Name;
    var type = pi.PropertyType;
    var value = pi.GetValue(obj, null);

    //now setup the UI control for this property and display the value
}

      

+1


source


I accidentally found something similar to this, I remembered I had this problem a while ago and thought I should share it.

Here's a simple example: http://blog.denouter.net/2008/08/simple-reflection-form.html . It uses reflection to create multiple controls based on object properties.

+1


source







All Articles