PropertyGrid: Hide base class properties, how?
Asked Answered
B

2

7

PropertyGrid... for users Id like to leave only several of them. But now I see all, and users would be confused when see something like Dock or Cursor and such... Hope it's clear for now...

Birch answered 14/8, 2011 at 1:32 Comment(0)
V
12

Use this attribute:

[Browsable(false)]
public bool AProperty {...} 

For the inherited properties:

[Browsable(false)]
public override bool AProperty {...} 

Another idea (since you are trying to hide all base class members):

public class MyCtrl : TextBox
{
  private ExtraProperties _extraProps = new ExtraProperties();

  public ExtraProperties ExtraProperties
  {
    get { return _extraProps; }
    set { _extraProps = value; }
  }
}

public class ExtraProperties
{
  private string _PropertyA = string.Empty;

  [Category("Text Properties"), Description("Value for Property A")]
  public string PropertyA {get; set;}

  [Category("Text Properties"), Description("Value for Property B")]
  public string PropertyB { get; set; }
}

and then for your property grid:

  MyCtrl tx = new MyCtrl();
  pg1.SelectedObject = tx.ExtraProperties;

The down side is it changes your access level of those properties from

tx.PropertyA = "foo";

to

tx.ExtraProperties.PropertyA = "foo";
Vinaigrette answered 14/8, 2011 at 1:35 Comment(3)
It's not about inherited class, I want to hide properties of the base class. In that case: TextBox props. How to hide base class props? that's the question.Birch
Yes, it works, I know. You'd see in my question the statement: "What technique is applicable in that case? Hiding? Each prop of the base class?"... I's just wondering maybe I could filter attributes... but seems like during runtime it's not possible, as all attributes are static to compiled assembly.Birch
The ExtraProperties idea has the added advantage of making serialization simpler.Gloom
C
8

To hide MyCtrl properties, use [Browsable(False)] attribute on the property.

[Browsable(false)]
public bool AProperty { get; set;}

To hide inherited proeprties, you need to override the base and apply the browsable attribute.

[Browsable(false)]
public override string InheritedProperty  { get; set;}

Note: You may need to add the virtual or new keyword depending on the circumstances.

A better approach would be to use a ControlDesigner. The designer has an override called PreFilterProperties that can be used to add extra attributes to the collection that has been extracted by the PropertyGrid.

Designer(typeof(MyControlDesigner))]
public class MyControl : TextBox
{
    // ...
}

public class MyControlDesigner : ...
{
    // ...

    protected override void PreFilterProperties(
                             IDictionary properties) 
    {
        base.PreFilterProperties (properties);

        // add the names of proeprties you wish to hide
        string[] propertiesToHide = 
                     {"MyProperty", "ErrorMessage"};  

        foreach(string propname in propertiesToHide)
        {
            prop = 
              (PropertyDescriptor)properties[propname];
            if(prop!=null)
            {
                AttributeCollection runtimeAttributes = 
                                           prop.Attributes;
                // make a copy of the original attributes 

                // but make room for one extra attribute

                Attribute[] attrs = 
                   new Attribute[runtimeAttributes.Count + 1];
                runtimeAttributes.CopyTo(attrs, 0);
                attrs[runtimeAttributes.Count] = 
                                new BrowsableAttribute(false);
                prop = 
                 TypeDescriptor.CreateProperty(this.GetType(), 
                             propname, prop.PropertyType,attrs);
                properties[propname] = prop;
            }            
        }
    }
}

You can add the names of proeprties you wish to hide to propertiesToHide which allows for a cleaner separation.

Credit where due: http://www.codeproject.com/KB/webforms/HidingProperties.aspx#

Circularize answered 14/8, 2011 at 1:39 Comment(10)
that's right.. thanks. what means ("<{0}:MyControl runat="server"></{0}:MyControl>") ? is it from ASP? I'm using WinForms...Birch
Yes. You can ignore that part for Winforms. I'll update my answer.Circularize
What do you mean by runtime? PropertyGrid is a design time thing, no?Circularize
No. There's PropertyGrid control... and I tried even in Design Time, it crashes form design... didn't help, sorry..Birch
You mean the ControlDesigner part crashes the form design or hiding the inherited properties crashes the form design??Circularize
prop = TypeDescriptor.CreateProperty(this.GetType(), propname, prop.PropertyType,attrs); Why this.GetType()... should be MyControl..???Birch
When add [Designer(typeof(MyControlDesigner))] it crushes. Then need to restart VS.Birch
It has to be the Type of the component that the property is a member of. msdn.microsoft.com/en-us/library/5yx7wa4c.aspxCircularize
@KirkRobb let us continue this discussion in chatCircularize
If using override, don’t forget to proxy set and get to the base class’s set and get manually.Barcellona

© 2022 - 2024 — McMap. All rights reserved.