Make all properties with specific Category name in

2019-07-29 05:59发布

问题:

I have a property Grid in my application which shows the properties of a selected control at run time.

Recently there was a requirement to add some extra properties to the already existing controls. To accommodate this a new category was introduced under which the newer properties were added.

Now I am looking for a mechanism to hide these newly added properties at run time based on a runtime condition in the application. But I don’t have a proper solution for this.

Newly added code:

    [ReadOnly(true)]
    [Browsable(true)]
    [Category("Extra")]
    public int? FormID { get; set; }

    [Browsable(true)]
    [Category("Extra")]
    public int? jrxml_Id { get; set; }

What I was expecting to work:

    [ReadOnly(true)]
    [Browsable(matchSomeRunTimeCondition)]
    [Category("Extra")]
    public int? FormID { get; set; }

    [Browsable(matchSomeRunTimeCondition)]
    [Category("Extra")]
    public int? jrxml_Id { get; set; }

Why it does not work?

Because Browsable Attribute can only accept Constant. And matchSomeRunTimeCondition is not a constant. A user can change it when-ever he wants while the application is still running.

In code if there is a function that I can use to make these invisible at run-time I will be really greatful if someone can help me write one such function or conditional statement like so:

If (property’s category == “Extra”) {

//Do not show this property in the propertygrid.

//Or in other words, make Browasable Attribute False at run time.

}

Different controls in my application have different properties that need to be hidden at run time.

I have a list of all those properties which I want to hide in each of the object selected in the application to be shown in the propertygrid.

But I need help in how to achieve this.

Note: I am open to setting the browsable property to true / false at compile time. But I want a mechanism to set this at run time in my application and need help in doing this please.

Looking for code solutions.

My coding environment (cannot change due to companies legacy support):

  • Visual Studio 2010
  • .Net 3.5
  • Windows 10 OS (Yeah I know)

回答1:

using the answer posted by TnTinMn, I modified my code as follows to make it hide all selective properties at run time.

private void ChangeVisibilityBasedOnMode( ref object[] v) {
    if (matchSomeRunTimeCondition) {
        List<string> PropertiesToHide = new List<string> {
            "FormID",
            "jrxml_Id",
        };
        foreach (var vObject in v) {
            var properties = GetProperties(vObject);
            foreach (var p in properties) {
                foreach (string hideProperty in PropertiesToHide ) {
                    if (p.Name.ToLower() == hideProperty.ToLower()) {
                        setBrowsableProperty(hideProperty, false, vObject);
                    }
                }
            }
        }
    }
}
private void setBrowsableProperty(string strPropertyName, bool bIsBrowsable, object vObject) {
    try {
        PropertyDescriptor theDescriptor = TypeDescriptor.GetProperties(vObject.GetType())[strPropertyName];
        BrowsableAttribute theDescriptorBrowsableAttribute = (BrowsableAttribute)theDescriptor.Attributes[typeof(BrowsableAttribute)];
        FieldInfo isBrowsable = theDescriptorBrowsableAttribute.GetType().GetField("Browsable", BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Instance);
        isBrowsable.SetValue(theDescriptorBrowsableAttribute, bIsBrowsable);
    } catch (Exception) { }
}

Also thanks to neoikon for his wonderful post (Conditional "Browsable" Attribute) from which I reached the final solution.



回答2:

This is what`s working for me

    private void SetVisibleSearchOptions(Type searchType, bool visible)
    {
        try
        {
            TypeDescriptor.AddAttributes(searchType, new BrowsableAttribute(visible));
        }
        catch (Exception ex)
        {

        }
    }