I am deep into using the Winforms designer (System.ComponentModel.Design namespace) in my C#/.NET solution so that my users have access to a form designer within my running application. Much of it works well, but I ran into a very specific problem: I encountered a property on a Microsoft control that appears only during design-time--i.e., for the design-time instance of the control. I want to suppress that property so that users cannot modify it when they place an instance of that control on my program's implementation of the Winform design surface.
Details: When a user drag-and-drops a control from the toolbox to the designer surface, I ensure that the newly added designer instance of the control is selected (so that it present resize handles and so the property grid displays that control's design-time properties). I bind the selected objects on the designer surface to the property grid by using the selection service's GetSelectedComponents() method and assigning the property grid's SelectedObjects property to the result.
Many of the controls on my toolbox are .NET controls. One of them is the .NET Winforms TableLayoutPanel control. When you place an instance of that control on a designer surface, you will see a Columns property in the bound PropertyGrid. I would like to suppress that property so that it doesn't appear in the PropertyGrid.
The issue is that this Columns property doesn't appear to exist in the properties list for the TableLayoutPanel type--so using selectedComponents[0].GetType().GetProperties(), for example, doesn't contain a Columns property. Also, I cannot create a new or override for the existing Columns property because it doesn't appear as an exposed property for the TableLayoutPanel control at design time--thus I cannot decorate it with the Browsable(false) attribute.
I can't seem to leverage PreFilterProperties or PostFilterProperties because I can't interact and customize the TableLayoutPanel's designer.
How can I suppress the Columns designer property for the TableLayoutPanel so that it doesn't appear in the PropertyGrid without having to write my own designer?
If you are trying to avoid writing
TableLayoutPanelDesigneryourself, then here is a workaround that I can suggest.ITypeDescriptorFilterServiceis the interface which is responsible for callingPreFilterPropertiesmethod of the designer. TheDesignSurfaceclass has a an instance of an implementation of this interface registered in itsServiceContainer. So you can remove the existing registered instance and register a new instance of your own implementation ofITypeDescriptorFilterService.In the new implementation, override
FilterPropertiesand do whatever you think is suitable, for example you can check if the type of the component isTableLayoutPanel, then don't call its designerPreFilterProperties.Then to wrap up the solution, you need to create your own design surface by deriving from
DesignSurfaceclass and removing the registeredITypeDescriptorFilterServiceand registering the desired instance which you created.Example
Just for your information, the name of the property which you are looking for is
ColumnStylesand it hasBrowsable(false)attribute by default. But the default designer ofTableLayoutPanelreplaces this property with a browsable version.What I've done in this example is stopping the designer from making those properties Visible.
First provide a custom implementation of
ITypeDescriptorFilterService. The following one is in fact the existing implementation inSystem.Designassembly which I've changed itsFilterPropertiesmethod and checked if the component isTableLayoutPanel, I've asked to do nothing.Then create a design surface by deriving from
DesignSurface:Then for example initialize the design surface this way:
Then run your designer application and you will see
ColumnsandRowsproperties are hidden as expected.You need to hide
ColumnCountandRowCountproperties and also the verbs assigned to editing/adding/removing columns and rows.