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...

2 Answers2

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";
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • 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. –  Aug 14 '11 at 01:39
  • 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. –  Aug 14 '11 at 03:12
  • The ExtraProperties idea has the added advantage of making serialization simpler. – BVernon Dec 25 '13 at 10:11
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#

Mrchief
  • 75,126
  • 20
  • 142
  • 189
  • that's right.. thanks. what means ("<{0}:MyControl runat="server">{0}:MyControl>") ? is it from ASP? I'm using WinForms... –  Aug 14 '11 at 01:50
  • Yes. You can ignore that part for Winforms. I'll update my answer. – Mrchief Aug 14 '11 at 01:51
  • What do you mean by runtime? `PropertyGrid` is a design time thing, no? – Mrchief Aug 14 '11 at 02:03
  • No. There's PropertyGrid control... and I tried even in Design Time, it crashes form design... didn't help, sorry.. –  Aug 14 '11 at 02:08
  • You mean the `ControlDesigner` part crashes the form design or hiding the inherited properties crashes the form design?? – Mrchief Aug 14 '11 at 02:26
  • prop = TypeDescriptor.CreateProperty(this.GetType(), propname, prop.PropertyType,attrs); Why this.GetType()... should be MyControl..??? –  Aug 14 '11 at 02:48
  • When add [Designer(typeof(MyControlDesigner))] it crushes. Then need to restart VS. –  Aug 14 '11 at 02:52
  • It has to be the `Type` of the component that the property is a member of. http://msdn.microsoft.com/en-us/library/5yx7wa4c.aspx – Mrchief Aug 14 '11 at 02:55
  • @KirkRobb let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2452/discussion-between-mrchief-and-kirk-robb) – Mrchief Aug 14 '11 at 02:56
  • If using `override`, don’t forget to proxy `set` and `get` to the base class’s `set` and `get` manually. – binki Aug 27 '14 at 14:47