views:

802

answers:

3

Hello

I would like to be able to set the visibility of a property on my property grid using App.config. I have tried :

[Browsable(bool.Parse(Sytem.Configuration.ConfigurationSettings.AppSettings["testBool"]))]

However Visual Studio 2008 would give me an error "An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type". Is there any way to set this bool on App.config?

+2  A: 

you can't do above in the app.config. This is design time based and your app.config is read and used at runtime.

klabranche
+1  A: 

The property grid uses reflection to figure out what properties to display and how to display them. You can't set this in any kind of config file. You need to apply this attribute to the property in the class itself.

Scott Dorman
+2  A: 

You can't do this via config; but you can control attributes by writing a custom component-model implementation; i.e. writing your own PropertyDescriptor, and using ICustomTypeDescriptor or TypeDescriptionProvider to associate it. Lots of work.


Update

I thought of a sneaky way to do it; see below, where we filter it to 2 of the properties using a string at runtime. If you don't own the type (to set the [TypeConverter]), then you can use:

TypeDescriptor.AddAttributes(typeof(Test),
    new TypeConverterAttribute(typeof(TestConverter)));

to associate the converter at runtime.

using System.Windows.Forms;
using System.ComponentModel;
using System.Collections.Generic;
using System;
class TestConverter : ExpandableObjectConverter
{
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, System.Attribute[] attributes)
    {
        PropertyDescriptorCollection orig = base.GetProperties(context, value, attributes);
        List<PropertyDescriptor> list = new List<PropertyDescriptor>(orig.Count);
        string propsToInclude = "Foo|Blop"; // from config
        foreach (string propName in propsToInclude.Split('|'))
        {
            PropertyDescriptor prop = orig.Find(propName, true);
            if (prop != null) list.Add(prop);
        }
        return new PropertyDescriptorCollection(list.ToArray());
    }
}
[TypeConverter(typeof(TestConverter))]
class Test
{
    public string Foo { get; set; }
    public string Bar { get; set; }
    public string Blop { get; set; }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Test test = new Test { Foo = "foo", Bar = "bar", Blop = "blop"};
        using (Form form = new Form())
        using (PropertyGrid grid = new PropertyGrid())
        {
            grid.Dock = DockStyle.Fill;
            form.Controls.Add(grid);
            grid.SelectedObject = test;
            Application.Run(form);
        }
    }
}
Marc Gravell
This is a very educated answer on the topic. Using ICustomTypeDescriptor or the other types associated with it (check MSDN to see what works best for your design) you can initialize your descriptors with configuration values, but you would have to do the work manually (like configuration; see System.Configuration.ConfigurationSection and the like for that) as the default type descriptors use attributes applied to assembly type information at compile-time.
TheXenocide