
Creating a Custom Designer to Shadow and Filter Properties
The MarqueeControlRootDesigner class provides the implementation for the root designer. In addition to this designer, which operates on the MarqueeControl, you will need a custom designer that is specifically associated with the MarqueeBorder control. This designer provides custom behavior that is appropriate in the context of the custom root designer.
Specifically, the MarqueeBorderDesigner will "shadow" and filter certain properties on the MarqueeBorder control, changing their interaction with the design environment.
Intercepting calls to a component's property accessor is known as "shadowing." It allows a designer to track the value set by the user and optionally pass that value to the component being designed.
For this example, the Visible()()() and Enabled()()() properties will be shadowed by the MarqueeBorderDesigner, which prevents the user from making the MarqueeBorder control invisible or disabled during design time.
Designers can also add and remove properties. For this example, the Padding()()() property will be removed at design time, because the MarqueeBorder control programmatically sets the padding based on the size of the lights specified by the LightSize property.
The base class for MarqueeBorderDesigner is ComponentDesigner, which has methods that can change the attributes, properties, and events exposed by a control at design time:
PreFilterProperties(IDictionary)
PostFilterProperties(IDictionary)
PreFilterAttributes(IDictionary)
PostFilterAttributes(IDictionary)
PreFilterEvents(IDictionary)
PostFilterEvents(IDictionary)
When changing the public interface of a component using these methods, you must follow these rules:
Add or remove items in the PreFilter methods only
Modify existing items in the PostFilter methods only
Always call the base implementation first in the PreFilter methods
Always call the base implementation last in the PostFilter methods
Adhering to these rules ensures that all designers in the design-time environment have a consistent view of all components being designed.
The ComponentDesigner class provides a dictionary for managing the values of shadowed properties, which relieves you of the need to create specific instance variables.
To create a custom designer to shadow and filter properties
Right-click the Design folder and add a new class. Give the source file a base name of "MarqueeBorderDesigner."
Open the MarqueeBorderDesigner source file in the Code Editor. At the top of the file, import the following namespaces:
Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Diagnostics
Imports System.Windows.Forms
Imports System.Windows.Forms.Design
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Windows.Forms;
using System.Windows.Forms.Design;
Change the declaration of MarqueeBorderDesigner to inherit from ParentControlDesigner.
Because the MarqueeBorder control can contain child controls, MarqueeBorderDesigner inherits from ParentControlDesigner, which handles the parent-child interaction.
Namespace MarqueeControlLibrary.Design
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Public Class MarqueeBorderDesigner
Inherits ParentControlDesigner
namespace MarqueeControlLibrary.Design
{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class MarqueeBorderDesigner : ParentControlDesigner
{
Override the base implementation of PreFilterProperties(IDictionary).
Protected Overrides Sub PreFilterProperties( _
ByVal properties As IDictionary)
MyBase.PreFilterProperties(properties)
If properties.Contains("Padding") Then
properties.Remove("Padding")
End If
properties("Visible") = _
TypeDescriptor.CreateProperty(GetType(MarqueeBorderDesigner), _
CType(properties("Visible"), PropertyDescriptor), _
New Attribute(-1) {})
properties("Enabled") = _
TypeDescriptor.CreateProperty(GetType(MarqueeBorderDesigner), _
CType(properties("Enabled"), _
PropertyDescriptor), _
New Attribute(-1) {})
End Sub
protected override void PreFilterProperties(IDictionary properties)
{
base.PreFilterProperties(properties);
if (properties.Contains("Padding"))
{
properties.Remove("Padding");
}
properties["Visible"] = TypeDescriptor.CreateProperty(
typeof(MarqueeBorderDesigner),
(PropertyDescriptor)properties["Visible"],
new Attribute[0]);
properties["Enabled"] = TypeDescriptor.CreateProperty(
typeof(MarqueeBorderDesigner),
(PropertyDescriptor)properties["Enabled"],
new Attribute[0]);
}
Implement the Enabled()()() and Visible()()() properties. These implementations shadow the control's properties.
Public Property Visible() As Boolean
Get
Return CBool(ShadowProperties("Visible"))
End Get
Set(ByVal Value As Boolean)
Me.ShadowProperties("Visible") = Value
End Set
End Property
Public Property Enabled() As Boolean
Get
Return CBool(ShadowProperties("Enabled"))
End Get
Set(ByVal Value As Boolean)
Me.ShadowProperties("Enabled") = Value
End Set
End Property
public bool Visible
{
get
{
return (bool)ShadowProperties["Visible"];
}
set
{
this.ShadowProperties["Visible"] = value;
}
}
public bool Enabled
{
get
{
return (bool)ShadowProperties["Enabled"];
}
set
{
this.ShadowProperties["Enabled"] = value;
}
}