ITypeDescriptorFilterService Interfaccia
Definizione
Fornisce un'interfaccia per modificare l'insieme dei descrittori di membro per un componente in modalità progettazione.Provides an interface to modify the set of member descriptors for a component in design mode.
public interface class ITypeDescriptorFilterService
public interface ITypeDescriptorFilterService
type ITypeDescriptorFilterService = interface
Public Interface ITypeDescriptorFilterService
- Derivato
Esempi
Nell'esempio di codice riportato di seguito viene illustrata ITypeDescriptorFilterService una finestra di progettazione che utilizza per filtrare l'insieme Button di attributi di qualsiasi nuovo o esistente per aggiungere un attributo della finestra di progettazione per una nuova finestra di progettazione prima di caricare o ricaricare la finestra di progettazione per il pulsante.The following code example demonstrates a designer that uses the ITypeDescriptorFilterService to filter the attributes collection of any new or existing Button to add a designer attribute for a new designer before loading or reloading the designer for the button.
Per usare l'esempio, aggiungere il codice a un progetto Windows Forms e caricare i componenti dalla libreria di classi nella casella degli strumenti.To use the example, add the code to a Windows Forms project and load the components from the class library into the Toolbox.
Vedere anche procedura dettagliata: Popolamento automatico della casella degli strumenti concomponenti personalizzati.Also see Walkthrough: Automatically Populating the Toolbox with Custom Components.
Aggiungere alcuni pulsanti al form.Add some buttons to your form. Aggiungere un ButtonDesignerFilterComponent
oggetto al form e verrà visualizzato nella barra dei componenti.Add a ButtonDesignerFilterComponent
to your form, and it will appear in the component tray. In viene aggiunto un ButtonDesignerFilterService
oggetto, che ITypeDescriptorFilterServiceimplementa, come provider di servizi in modalità progettazione. ButtonDesignerFilterComponent
The ButtonDesignerFilterComponent
will add a ButtonDesignerFilterService
, which implements ITypeDescriptorFilterService, as a design mode service provider. Gli oggetti nuovi Button o esistenti nel form inizieranno a colorarsi ButtonDesignerFilterService
dopo che sostituisce la finestra di progettazione per ogni pulsante nuovo e ColorCycleButtonDesigner
esistente con un.Existing or new Button objects on the form will begin color cycling after the ButtonDesignerFilterService
replaces the designer for each existing and new button with a ColorCycleButtonDesigner
. Quando si sposta il puntatore del mouse su di essi, i pulsanti vengono colorati e in alternativa continuano a scorrere o reimpostare i colori di MouseLeave
sfondo e di primo piano per gli eventi.The buttons will color cycle when you move the mouse pointer over them, and alternately continue cycling or reset the background and foreground colors on MouseLeave
events. Ai Button nuovi oggetti verrà assegnato l' ColorCycleButtonDesigner
oggetto tramite FilterAttributes il metodo dell' ButtonDesignerFilterService
oggetto che è stato caricato, fino ButtonDesignerFilterComponent
a quando l'oggetto non viene eliminato e ITypeDescriptorFilterServicesostituisce quello originale.New Button objects will be given the ColorCycleButtonDesigner
through the FilterAttributes method of the ButtonDesignerFilterService
that has been loaded, until the ButtonDesignerFilterComponent
is disposed and replaces the original ITypeDescriptorFilterService. La ColorCycleButton
classe in questo esempio Button è associata a un oggetto ColorCycleButtonDesigner
.The ColorCycleButton
class in this example is a Button associated with a ColorCycleButtonDesigner
.
#using <System.Windows.Forms.dll>
#using <System.Drawing.dll>
#using <System.Design.dll>
#using <System.dll>
using namespace System;
using namespace System::Collections;
using namespace System::ComponentModel;
using namespace System::ComponentModel::Design;
using namespace System::ComponentModel::Design::Serialization;
using namespace System::Drawing;
using namespace System::Reflection;
using namespace System::Timers;
using namespace System::Windows::Forms;
using namespace System::Windows::Forms::Design;
// Designer for a Button control which cycles the background color.
public ref class ColorCycleButtonDesigner: public System::Windows::Forms::Design::ControlDesigner
{
private:
System::Windows::Forms::Timer^ timer1;
Color initial_bcolor;
Color initial_fcolor;
int r;
int g;
int b;
bool ru;
bool gu;
bool bu;
bool continue_;
public:
ColorCycleButtonDesigner()
{
timer1 = gcnew System::Windows::Forms::Timer;
timer1->Interval = 50;
timer1->Tick += gcnew EventHandler( this, &ColorCycleButtonDesigner::Elapsed );
ru = true;
gu = false;
bu = true;
continue_ = false;
timer1->Start();
}
private:
void Elapsed( Object^ /*sender*/, EventArgs^ /*e*/ )
{
this->Control->BackColor = Color::FromArgb( r % 255, g % 255, b % 255 );
this->Control->Refresh();
// Updates color.
if ( ru )
r += 10;
else
if ( r > 10 )
r -= 10;
if ( gu )
g += 10;
else
if ( g > 10 )
g -= 10;
if ( bu )
b += 10;
else
if ( b > 10 )
b -= 10;
// Randomly switches direction of color component values.
Random^ rand = gcnew Random;
for ( int i = 0; i < 4; i++ )
switch ( rand->Next( 0, 2 ) )
{
case 0:
if ( ru )
ru = false;
else
ru = true;
break;
case 1:
if ( gu )
gu = false;
else
gu = true;
break;
case 2:
if ( bu )
bu = false;
else
bu = true;
break;
}
this->Control->ForeColor = Color::FromArgb( (this->Control->BackColor.R + 128) % 255, (this->Control->BackColor.G + 128) % 255, (this->Control->BackColor.B + 128) % 255 );
}
protected:
virtual void OnMouseEnter() override
{
if ( !timer1->Enabled )
{
initial_bcolor = this->Control->BackColor;
initial_fcolor = this->Control->ForeColor;
r = initial_bcolor.R;
g = initial_bcolor.G;
b = initial_bcolor.B;
timer1->Start();
}
}
virtual void OnMouseLeave() override
{
if ( !continue_ )
{
continue_ = true;
timer1->Stop();
}
else
continue_ = false;
this->Control->BackColor = initial_bcolor;
this->Control->ForeColor = initial_fcolor;
}
public:
~ColorCycleButtonDesigner()
{
timer1->Stop();
this->Control->BackColor = initial_bcolor;
this->Control->ForeColor = initial_fcolor;
}
};
// Provides a TypeDescriptorFilterService to add the
// ColorCycleButtonDesigner using a DesignerAttribute.
public ref class ButtonDesignerFilterService: public System::ComponentModel::Design::ITypeDescriptorFilterService
{
public:
ITypeDescriptorFilterService^ oldService;
ButtonDesignerFilterService(){}
ButtonDesignerFilterService( ITypeDescriptorFilterService^ oldService_ )
{
// Stores any previous ITypeDescriptorFilterService to implement service chaining.
this->oldService = oldService_;
}
virtual bool FilterAttributes( System::ComponentModel::IComponent^ component, System::Collections::IDictionary^ attributes )
{
if ( oldService != nullptr )
oldService->FilterAttributes( component, attributes );
// Creates a designer attribute to compare its TypeID with the TypeID of existing attributes of the component.
DesignerAttribute^ da = gcnew DesignerAttribute( ColorCycleButtonDesigner::typeid );
// Adds the designer attribute if the attribute collection does not contain a DesignerAttribute of the same TypeID.
if ( dynamic_cast<System::Windows::Forms::Button^>(component) && attributes->Contains( da->TypeId ) )
attributes[ da->TypeId ] = da;
return true;
}
virtual bool FilterEvents( System::ComponentModel::IComponent^ component, System::Collections::IDictionary^ events )
{
if ( oldService != nullptr )
oldService->FilterEvents( component, events );
return true;
}
virtual bool FilterProperties( System::ComponentModel::IComponent^ component, System::Collections::IDictionary^ properties )
{
if ( oldService != nullptr )
oldService->FilterProperties( component, properties );
return true;
}
};
// System.Windows.Forms.Button associated with the ColorCycleButtonDesigner.
[Designer(ColorCycleButtonDesigner::typeid)]
public ref class ColorCycleButton: public System::Windows::Forms::Button
{
public:
ColorCycleButton(){}
};
// Provides a designer that can add a ColorCycleButtonDesigner to each
// button in a design time project using the ButtonDesignerFilterService
// ITypeDescriptorFilterService.
public ref class ButtonDesignerFilterComponentDesigner: public System::ComponentModel::Design::ComponentDesigner
{
private:
// Indicates whether the service has been loaded.
bool serviceloaded;
// Stores any old ITypeDescriptorFilterService to restore later.
ITypeDescriptorFilterService^ oldservice;
public:
ButtonDesignerFilterComponentDesigner()
{
serviceloaded = false;
}
// Loads the new ITypeDescriptorFilterService and reloads the
// designers for each button.
virtual void Initialize( System::ComponentModel::IComponent^ component ) override
{
ComponentDesigner::Initialize( component );
// Loads the custom service if it has not been loaded already
LoadService();
// Build list of buttons from Container.Components.
ArrayList^ buttons = gcnew ArrayList;
IEnumerator^ myEnum = this->Component->Site->Container->Components->GetEnumerator();
while ( myEnum->MoveNext() )
{
IComponent^ c = safe_cast<IComponent^>(myEnum->Current);
if ( c->GetType() == System::Windows::Forms::Button::typeid )
buttons->Add( dynamic_cast<System::Windows::Forms::Button^>(c) );
}
if ( buttons->Count > 0 )
{
// Tests each Button for an existing
// ColorCycleButtonDesigner;
// if it has no designer of type
// ColorCycleButtonDesigner, adds a designer.
IEnumerator^ myEnum1 = buttons->GetEnumerator();
while ( myEnum1->MoveNext() )
{
Button^ b = safe_cast<Button^>(myEnum1->Current);
bool loaddesigner = true;
// Gets the attributes for each button.
AttributeCollection^ ac = TypeDescriptor::GetAttributes( b );
for ( int i = 0; i < ac->Count; i++ )
{
// If designer attribute is not for a
// ColorCycleButtonDesigner, adds a new
// ColorCycleButtonDesigner.
if ( dynamic_cast<DesignerAttribute^>(ac[ i ]) )
{
DesignerAttribute^ da = dynamic_cast<DesignerAttribute^>(ac[ i ]);
if ( da->DesignerTypeName->Substring( da->DesignerTypeName->LastIndexOf( "." ) + 1 )->Equals( "ColorCycleButtonDesigner" ) )
loaddesigner = false;
}
}
if ( loaddesigner )
{
// Saves the button location so that it
// can be repositioned.
Point p = b->Location;
// Gets an IMenuCommandService to cut and
// paste control in order to register with
// selection and movement interface after
// designer is changed without reloading.
IMenuCommandService^ imcs = dynamic_cast<IMenuCommandService^>(this->GetService( IMenuCommandService::typeid ));
if ( imcs == nullptr )
throw gcnew Exception( "Could not obtain IMenuCommandService interface." );
// Gets an ISelectionService to select the
// button so that it can be cut and pasted.
ISelectionService^ iss = dynamic_cast<ISelectionService^>(this->GetService( ISelectionService::typeid ));
if ( iss == nullptr )
throw gcnew Exception( "Could not obtain ISelectionService interface." );
array<IComponent^>^temp0 = {b};
iss->SetSelectedComponents( dynamic_cast<ICollection^>(temp0), SelectionTypes::Normal );
// Invoke Cut and Paste.
imcs->GlobalInvoke( StandardCommands::Cut );
imcs->GlobalInvoke( StandardCommands::Paste );
// Regains reference to button from
// selection service.
System::Windows::Forms::Button^ b2 = dynamic_cast<System::Windows::Forms::Button^>(iss->PrimarySelection);
iss->SetSelectedComponents( nullptr );
// Refreshes TypeDescriptor properties of
// button to load new attributes from
// ButtonDesignerFilterService.
TypeDescriptor::Refresh( b2 );
b2->Location = p;
b2->Focus();
}
}
}
}
private:
// Loads a ButtonDesignerFilterService ITypeDescriptorFilterService
// to add ColorCycleButtonDesigner designers to each button.
void LoadService()
{
// If no custom ITypeDescriptorFilterService is loaded,
// loads it now.
if ( !serviceloaded )
{
// Stores the current ITypeDescriptorFilterService
// to restore later.
ITypeDescriptorFilterService^ tdfs = dynamic_cast<ITypeDescriptorFilterService^>(this->Component->Site->GetService( ITypeDescriptorFilterService::typeid ));
if ( tdfs != nullptr )
oldservice = tdfs;
// Retrieves an IDesignerHost interface to use to
// remove and add services.
IDesignerHost^ dh = dynamic_cast<IDesignerHost^>(this->Component->Site->GetService( IDesignerHost::typeid ));
if ( dh == nullptr )
throw gcnew Exception( "Could not obtain IDesignerHost interface." );
// Removes standard ITypeDescriptorFilterService.
dh->RemoveService( ITypeDescriptorFilterService::typeid );
// Adds new custom ITypeDescriptorFilterService.
dh->AddService( ITypeDescriptorFilterService::typeid, gcnew ButtonDesignerFilterService );
serviceloaded = true;
}
}
// Removes the custom service and reloads any stored,
// preexisting service.
void RemoveService()
{
IDesignerHost^ dh = dynamic_cast<IDesignerHost^>(this->GetService( IDesignerHost::typeid ));
if ( dh == nullptr )
throw gcnew Exception( "Could not obtain IDesignerHost interface." );
dh->RemoveService( ITypeDescriptorFilterService::typeid );
if ( oldservice != nullptr )
dh->AddService( ITypeDescriptorFilterService::typeid, oldservice );
serviceloaded = false;
}
public:
~ButtonDesignerFilterComponentDesigner()
{
if ( serviceloaded )
RemoveService();
}
};
// Component to host the ButtonDesignerFilterComponentDesigner that loads the
// ButtonDesignerFilterService ITypeDescriptorFilterService.
[Designer(ButtonDesignerFilterComponentDesigner::typeid)]
public ref class ButtonDesignerFilterComponent: public System::ComponentModel::Component
{
public:
ButtonDesignerFilterComponent( System::ComponentModel::IContainer^ container )
{
container->Add( this );
}
ButtonDesignerFilterComponent(){}
};
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Reflection;
using System.Timers;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace ITypeDescriptorFilterSample
{
// Component to host the ButtonDesignerFilterComponentDesigner that loads the
// ButtonDesignerFilterService ITypeDescriptorFilterService.
[Designer(typeof(ButtonDesignerFilterComponentDesigner))]
public class ButtonDesignerFilterComponent : System.ComponentModel.Component
{
public ButtonDesignerFilterComponent(System.ComponentModel.IContainer container)
{
container.Add(this);
}
public ButtonDesignerFilterComponent()
{}
}
// Provides a designer that can add a ColorCycleButtonDesigner to each
// button in a design time project using the ButtonDesignerFilterService
// ITypeDescriptorFilterService.
public class ButtonDesignerFilterComponentDesigner : System.ComponentModel.Design.ComponentDesigner
{
// Indicates whether the service has been loaded.
private bool serviceloaded = false;
// Stores any old ITypeDescriptorFilterService to restore later.
private ITypeDescriptorFilterService oldservice = null;
public ButtonDesignerFilterComponentDesigner()
{}
// Loads the new ITypeDescriptorFilterService and reloads the
// designers for each button.
public override void Initialize(System.ComponentModel.IComponent component)
{
base.Initialize(component);
// Loads the custom service if it has not been loaded already
LoadService();
// Build list of buttons from Container.Components.
ArrayList buttons = new ArrayList();
foreach(IComponent c in this.Component.Site.Container.Components)
if(c.GetType() == typeof(System.Windows.Forms.Button))
buttons.Add((System.Windows.Forms.Button)c);
if(buttons.Count > 0)
{
// Tests each Button for an existing
// ColorCycleButtonDesigner;
// if it has no designer of type
// ColorCycleButtonDesigner, adds a designer.
foreach(System.Windows.Forms.Button b in buttons)
{
bool loaddesigner = true;
// Gets the attributes for each button.
AttributeCollection ac = TypeDescriptor.GetAttributes(b);
for(int i=0; i<ac.Count; i++)
{
// If designer attribute is not for a
// ColorCycleButtonDesigner, adds a new
// ColorCycleButtonDesigner.
if( ac[i] is DesignerAttribute )
{
DesignerAttribute da = (DesignerAttribute)ac[i];
if( da.DesignerTypeName.Substring(da.DesignerTypeName.LastIndexOf(".")+1) == "ColorCycleButtonDesigner" )
loaddesigner = false;
}
}
if(loaddesigner)
{
// Saves the button location so that it
// can be repositioned.
Point p = b.Location;
// Gets an IMenuCommandService to cut and
// paste control in order to register with
// selection and movement interface after
// designer is changed without reloading.
IMenuCommandService imcs = (IMenuCommandService)this.GetService(typeof(IMenuCommandService));
if( imcs == null )
throw new Exception("Could not obtain IMenuCommandService interface.");
// Gets an ISelectionService to select the
// button so that it can be cut and pasted.
ISelectionService iss = (ISelectionService)this.GetService(typeof(ISelectionService));
if( iss == null)
throw new Exception("Could not obtain ISelectionService interface.");
iss.SetSelectedComponents(new IComponent[] { b }, SelectionTypes.Auto);
// Invoke Cut and Paste.
imcs.GlobalInvoke(StandardCommands.Cut);
imcs.GlobalInvoke(StandardCommands.Paste);
// Regains reference to button from
// selection service.
System.Windows.Forms.Button b2 = (System.Windows.Forms.Button)iss.PrimarySelection;
iss.SetSelectedComponents(null);
// Refreshes TypeDescriptor properties of
// button to load new attributes from
// ButtonDesignerFilterService.
TypeDescriptor.Refresh(b2);
b2.Location = p;
b2.Focus();
}
}
}
}
// Loads a ButtonDesignerFilterService ITypeDescriptorFilterService
// to add ColorCycleButtonDesigner designers to each button.
private void LoadService()
{
// If no custom ITypeDescriptorFilterService is loaded,
// loads it now.
if(!serviceloaded)
{
// Stores the current ITypeDescriptorFilterService
// to restore later.
ITypeDescriptorFilterService tdfs = (ITypeDescriptorFilterService)this.Component.Site.GetService(typeof(ITypeDescriptorFilterService));
if( tdfs != null )
oldservice = tdfs;
// Retrieves an IDesignerHost interface to use to
// remove and add services.
IDesignerHost dh = (IDesignerHost)this.Component.Site.GetService(typeof(IDesignerHost));
if( dh == null )
throw new Exception("Could not obtain IDesignerHost interface.");
// Removes standard ITypeDescriptorFilterService.
dh.RemoveService(typeof(ITypeDescriptorFilterService));
// Adds new custom ITypeDescriptorFilterService.
dh.AddService(typeof(ITypeDescriptorFilterService), new ButtonDesignerFilterService());
serviceloaded = true;
}
}
// Removes the custom service and reloads any stored,
// preexisting service.
private void RemoveService()
{
IDesignerHost dh = (IDesignerHost)this.GetService(typeof(IDesignerHost));
if( dh == null )
throw new Exception("Could not obtain IDesignerHost interface.");
dh.RemoveService(typeof(ITypeDescriptorFilterService));
if( oldservice != null )
dh.AddService(typeof(ITypeDescriptorFilterService), oldservice);
serviceloaded = false;
}
protected override void Dispose(bool disposing)
{
if(serviceloaded)
RemoveService();
}
}
// Provides a TypeDescriptorFilterService to add the
// ColorCycleButtonDesigner using a DesignerAttribute.
public class ButtonDesignerFilterService : System.ComponentModel.Design.ITypeDescriptorFilterService
{
public ITypeDescriptorFilterService oldService = null;
public ButtonDesignerFilterService()
{}
public ButtonDesignerFilterService(ITypeDescriptorFilterService oldService_)
{
// Stores any previous ITypeDescriptorFilterService to implement service chaining.
this.oldService = oldService_;
}
public bool FilterAttributes(System.ComponentModel.IComponent component, System.Collections.IDictionary attributes)
{
if(oldService != null)
oldService.FilterAttributes(component, attributes);
// Creates a designer attribute to compare its TypeID with the TypeID of existing attributes of the component.
DesignerAttribute da = new DesignerAttribute(typeof(ColorCycleButtonDesigner));
// Adds the designer attribute if the attribute collection does not contain a DesignerAttribute of the same TypeID.
if(component is System.Windows.Forms.Button && attributes.Contains(da.TypeId))
attributes[da.TypeId]=da;
return true;
}
public bool FilterEvents(System.ComponentModel.IComponent component, System.Collections.IDictionary events)
{
if(oldService != null)
oldService.FilterEvents(component, events);
return true;
}
public bool FilterProperties(System.ComponentModel.IComponent component, System.Collections.IDictionary properties)
{
if(oldService != null)
oldService.FilterProperties(component, properties);
return true;
}
}
// Designer for a Button control which cycles the background color.
public class ColorCycleButtonDesigner : System.Windows.Forms.Design.ControlDesigner
{
private System.Windows.Forms.Timer timer1;
private Color initial_bcolor, initial_fcolor;
private int r, g, b;
private bool ru, gu, bu, continue_;
public ColorCycleButtonDesigner()
{
timer1 = new System.Windows.Forms.Timer();
timer1.Interval = 50;
timer1.Tick += new EventHandler(this.Elapsed);
ru = true;
gu = false;
bu = true;
continue_ = false;
timer1.Start();
}
private void Elapsed(object sender, EventArgs e)
{
this.Control.BackColor = Color.FromArgb(r%255, g%255, b%255);
this.Control.Refresh();
// Updates color.
if(ru)
r+=10;
else if(r>10)
r-=10;
if(gu)
g+=10;
else if(g>10)
g-=10;
if(bu)
b+=10;
else if(b>10)
b-=10;
// Randomly switches direction of color component values.
Random rand = new Random();
for(int i=0; i<4; i++)
switch(rand.Next(0, 2))
{
case 0:
if(ru)
ru=false;
else
ru=true;
break;
case 1:
if(gu)
gu=false;
else
gu=true;
break;
case 2:
if(bu)
bu=false;
else
bu=true;
break;
}
this.Control.ForeColor = Color.FromArgb((this.Control.BackColor.R+128)%255, (this.Control.BackColor.G+128)%255, (this.Control.BackColor.B+128)%255);
}
protected override void OnMouseEnter()
{
if(!timer1.Enabled)
{
initial_bcolor = this.Control.BackColor;
initial_fcolor = this.Control.ForeColor;
r = initial_bcolor.R;
g = initial_bcolor.G;
b = initial_bcolor.B;
timer1.Start();
}
}
protected override void OnMouseLeave()
{
if(!continue_)
{
continue_ = true;
timer1.Stop();
}
else
continue_ = false;
this.Control.BackColor = initial_bcolor;
this.Control.ForeColor = initial_fcolor;
}
protected override void Dispose(bool disposing)
{
timer1.Stop();
this.Control.BackColor = initial_bcolor;
this.Control.ForeColor = initial_fcolor;
base.Dispose(disposing);
}
}
// System.Windows.Forms.Button associated with the ColorCycleButtonDesigner.
[Designer(typeof(ColorCycleButtonDesigner))]
public class ColorCycleButton : System.Windows.Forms.Button
{
public ColorCycleButton()
{}
}
}
Imports System.Collections
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.ComponentModel.Design.Serialization
Imports System.Drawing
Imports System.Reflection
Imports System.Timers
Imports System.Windows.Forms
Imports System.Windows.Forms.Design
Namespace ITypeDescriptorFilterSample
' Component to host the ButtonDesignerFilterComponentDesigner that loads the
' ButtonDesignerFilterService ITypeDescriptorFilterService.
<Designer(GetType(ButtonDesignerFilterComponentDesigner))> _
Public Class ButtonDesignerFilterComponent
Inherits System.ComponentModel.Component
Public Sub New(ByVal container As System.ComponentModel.IContainer)
container.Add(Me)
End Sub
Public Sub New()
End Sub
End Class
' Provides a designer that can add a ColorCycleButtonDesigner to each
' button in a design time project using the ButtonDesignerFilterService
' ITypeDescriptorFilterService.
Public Class ButtonDesignerFilterComponentDesigner
Inherits System.ComponentModel.Design.ComponentDesigner
' Indicates whether the service has been loaded.
Private serviceloaded As Boolean = False
' Stores any old ITypeDescriptorFilterService to restore later.
Private oldservice As ITypeDescriptorFilterService = Nothing
Public Sub New()
End Sub
' Loads the new ITypeDescriptorFilterService and reloads the
' designers for each Button.
Public Overrides Sub Initialize(ByVal component As System.ComponentModel.IComponent)
MyBase.Initialize(component)
' Loads the custom service if it has not been loaded already.
LoadService()
' Build list of buttons from Container.Components.
Dim buttons As New ArrayList()
Dim c As IComponent
For Each c In Me.Component.Site.Container.Components
If TypeOf c Is System.Windows.Forms.Button Then
buttons.Add(CType(c, System.Windows.Forms.Button))
End If
Next c
If buttons.Count > 0 Then
' Tests each Button for an existing
' ColorCycleButtonDesigner;
' if it has no designer of type
' ColorCycleButtonDesigner, adds a designer.
Dim b As System.Windows.Forms.Button
For Each b In buttons
Dim loaddesigner As Boolean = True
' Gets the attributes for each button.
Dim ac As AttributeCollection = TypeDescriptor.GetAttributes(b)
Dim i As Integer
For i = 0 To ac.Count - 1
' If designer attribute is not for a
' ColorCycleButtonDesigner, adds a new
' ColorCycleButtonDesigner.
If TypeOf ac(i) Is DesignerAttribute Then
Dim da As DesignerAttribute = CType(ac(i), DesignerAttribute)
If da.DesignerTypeName.Substring((da.DesignerTypeName.LastIndexOf(".") + 1)) = "ColorCycleButtonDesigner" Then
loaddesigner = False
End If
End If
Next i
If loaddesigner Then
' Saves the button location so that it
' can be repositioned.
Dim p As Point = b.Location
' Gets an IMenuCommandService to cut and
' paste control in order to register with
' selection and movement interface after
' designer is changed without reloading.
Dim imcs As IMenuCommandService = CType(Me.GetService(GetType(IMenuCommandService)), IMenuCommandService)
If imcs Is Nothing Then
Throw New Exception("Could not obtain IMenuCommandService interface.")
End If
' Gets an ISelectionService to select the
' button so that it can be cut and pasted.
Dim iss As ISelectionService = CType(Me.GetService(GetType(ISelectionService)), ISelectionService)
If iss Is Nothing Then
Throw New Exception("Could not obtain ISelectionService interface.")
End If
iss.SetSelectedComponents(New IComponent() {b}, SelectionTypes.Auto)
' Invoke Cut and Paste.
imcs.GlobalInvoke(StandardCommands.Cut)
imcs.GlobalInvoke(StandardCommands.Paste)
' Regains reference to button from
' selection service.
Dim b2 As System.Windows.Forms.Button = CType(iss.PrimarySelection, System.Windows.Forms.Button)
iss.SetSelectedComponents(Nothing)
' Refreshes TypeDescriptor properties of
' button to load new attributes from
' ButtonDesignerFilterService.
TypeDescriptor.Refresh(b2)
b2.Location = p
b2.Focus()
End If
Next b
End If
End Sub
' Loads a ButtonDesignerFilterService ITypeDescriptorFilterService
' to add ColorCycleButtonDesigner designers to each button.
Private Sub LoadService()
' If no custom ITypeDescriptorFilterService is loaded,
' loads it now.
If Not serviceloaded Then
' Stores the current ITypeDescriptorFilterService
' to restore later.
Dim tdfs As ITypeDescriptorFilterService = CType(Me.Component.Site.GetService(GetType(ITypeDescriptorFilterService)), ITypeDescriptorFilterService)
If (tdfs IsNot Nothing) Then
oldservice = tdfs
End If
' Retrieves an IDesignerHost interface to use to
' remove and add services.
Dim dh As IDesignerHost = CType(Me.Component.Site.GetService(GetType(IDesignerHost)), IDesignerHost)
If dh Is Nothing Then
Throw New Exception("Could not obtain IDesignerHost interface.")
End If
' Removes the standard ITypeDescriptorFilterService.
dh.RemoveService(GetType(ITypeDescriptorFilterService))
' Adds the new custom ITypeDescriptorFilterService.
dh.AddService(GetType(ITypeDescriptorFilterService), New ButtonDesignerFilterService())
serviceloaded = True
End If
End Sub
' Removes the custom service and reloads any stored,
' preexisting service.
Private Sub RemoveService()
Dim dh As IDesignerHost = CType(Me.GetService(GetType(IDesignerHost)), IDesignerHost)
If dh Is Nothing Then
Throw New Exception("Could not obtain IDesignerHost interface.")
End If
dh.RemoveService(GetType(ITypeDescriptorFilterService))
If (oldservice IsNot Nothing) Then
dh.AddService(GetType(ITypeDescriptorFilterService), oldservice)
End If
serviceloaded = False
End Sub
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If serviceloaded Then
RemoveService()
End If
End Sub
End Class
' Provides a TypeDescriptorFilterService to add the
' ColorCycleButtonDesigner using a DesignerAttribute.
Public Class ButtonDesignerFilterService
Implements System.ComponentModel.Design.ITypeDescriptorFilterService
Public oldService As ITypeDescriptorFilterService = Nothing
Public Sub New()
End Sub
Public Sub New(ByVal oldService_ As ITypeDescriptorFilterService)
' Stores any previous ITypeDescriptorFilterService to implement service chaining.
Me.oldService = oldService_
End Sub
Public Function FilterAttributes(ByVal component As System.ComponentModel.IComponent, ByVal attributes As System.Collections.IDictionary) As Boolean Implements ITypeDescriptorFilterService.FilterAttributes
If (oldService IsNot Nothing) Then
oldService.FilterAttributes(component, attributes)
End If
' Creates a designer attribute to compare its TypeID with the TypeID of existing attributes of the component.
Dim da As New DesignerAttribute(GetType(ColorCycleButtonDesigner))
' Adds the designer attribute if the attribute collection does not contain a DesignerAttribute of the same TypeID.
If TypeOf component Is System.Windows.Forms.Button And attributes.Contains(da.TypeId) Then
attributes(da.TypeId) = da
End If
Return True
End Function
Public Function FilterEvents(ByVal component As System.ComponentModel.IComponent, ByVal events As System.Collections.IDictionary) As Boolean Implements ITypeDescriptorFilterService.FilterEvents
If (oldService IsNot Nothing) Then
oldService.FilterEvents(component, events)
End If
Return True
End Function
Public Function FilterProperties(ByVal component As System.ComponentModel.IComponent, ByVal properties As System.Collections.IDictionary) As Boolean Implements ITypeDescriptorFilterService.FilterProperties
If (oldService IsNot Nothing) Then
oldService.FilterProperties(component, properties)
End If
Return True
End Function
End Class
' Designer for a Button control which cycles the background color.
Public Class ColorCycleButtonDesigner
Inherits System.Windows.Forms.Design.ControlDesigner
Private timer1 As System.Windows.Forms.Timer
Private initial_bcolor, initial_fcolor As Color
Private r, g, b As Integer
Private ru, gu, bu, continue_ As Boolean
Public Sub New()
timer1 = New System.Windows.Forms.Timer()
timer1.Interval = 50
AddHandler timer1.Tick, AddressOf Me.Elapsed
ru = True
gu = False
bu = True
continue_ = False
timer1.Start()
End Sub
Private Sub Elapsed(ByVal sender As Object, ByVal e As EventArgs)
Me.Control.BackColor = Color.FromArgb(r Mod 255, g Mod 255, b Mod 255)
Me.Control.Refresh()
' Updates color.
If ru Then
r += 10
Else
If r > 10 Then
r -= 10
End If
End If
If gu Then
g += 10
Else
If g > 10 Then
g -= 10
End If
End If
If bu Then
b += 10
Else
If b > 10 Then
b -= 10
End If
End If
' Randomly switches direction of color component values.
Dim rand As New Random()
Dim i As Integer
For i = 0 To 3
Select Case rand.Next(0, 2)
Case 0
If ru Then
ru = False
Else
ru = True
End If
Case 1
If gu Then
gu = False
Else
gu = True
End If
Case 2
If bu Then
bu = False
Else
bu = True
End If
End Select
Next i
Me.Control.ForeColor = Color.FromArgb((Me.Control.BackColor.R + 128) Mod 255, (Me.Control.BackColor.G + 128) Mod 255, (Me.Control.BackColor.B + 128) Mod 255)
End Sub
Protected Overrides Sub OnMouseEnter()
If Not timer1.Enabled Then
initial_bcolor = Me.Control.BackColor
initial_fcolor = Me.Control.ForeColor
r = initial_bcolor.R
g = initial_bcolor.G
b = initial_bcolor.B
timer1.Start()
End If
End Sub
Protected Overrides Sub OnMouseLeave()
If Not continue_ Then
continue_ = True
timer1.Stop()
Else
continue_ = False
End If
Me.Control.BackColor = initial_bcolor
Me.Control.ForeColor = initial_fcolor
End Sub
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
timer1.Stop()
Me.Control.BackColor = initial_bcolor
Me.Control.ForeColor = initial_fcolor
MyBase.Dispose(disposing)
End Sub
End Class
' System.Windows.Forms.Button associated with the ColorCycleButtonDesigner.
<Designer(GetType(ColorCycleButtonDesigner))> _
Public Class ColorCycleButton
Inherits System.Windows.Forms.Button
Public Sub New()
End Sub
End Class
End Namespace
Commenti
L' ITypeDescriptorFilterService interfaccia fornisce un'interfaccia che consente di modificare le proprietà, gli eventi e gli attributi a livello di classe di un componente in fase di progettazione.The ITypeDescriptorFilterService interface provides an interface that allows modification of the properties, events, and class-level attributes of a component at design time. Questa modifica viene eseguita tramite il set di descrittori fornito da un componente tramite TypeDescriptorun oggetto.This modification occurs through the set of descriptors that a component provides through a TypeDescriptor. Il descrittore di tipo eseguirà una query sul ITypeDescriptorFilterService sito di un componente per il servizio e, se esiste, il descrittore di tipo passerà tutti i metadati raccolti al servizio.The type descriptor will query a component's site for the ITypeDescriptorFilterService service and, if it exists, the type descriptor will pass all metadata it has collected to this service. Il servizio può quindi modificare i metadati aggiungendo, rimuovendo e modificando le caratteristiche esistenti del componente.The service can then modify the metadata by adding, removing, and altering existing characteristics of the component.
È ad esempio possibile modificare le proprietà di un componente tramite una chiamata al FilterProperties metodo.For example, the properties of a component can be modified through a call to the FilterProperties method. Il servizio Filter ottiene un dizionario che contiene i nomi delle proprietà e i relativi descrittori di PropertyDescriptorproprietà di tipo.The filter service obtains a dictionary that contains property names and their property descriptors of type PropertyDescriptor. Le modifiche vengono implementate usando la logica seguente.The modifications are implemented using the following logic.
ModificaModification | ImplementazioneImplementation |
---|---|
RimozioneRemoval | Elimina la voce corrispondente nel dizionario.Delete the corresponding entry in the dictionary. |
AddizioneAddition | Aggiungere la voce appropriata al dizionario.Add the appropriate entry to the dictionary. |
AlterazioneAlteration | Chiamare i metodi del descrittore di proprietà esistenti, sostituire la voce del descrittore di proprietà associata oppure sostituire l'intera coppia chiave/valore della proprietà nel dizionario.Call existing property descriptor methods, replace the associated property descriptor entry, or replace the entire property key/value pair in the dictionary. |
Il valore restituito di FilterProperties determina se questo set di proprietà è fisso.The return value of FilterProperties determines if this set of properties is fixed. Se questo metodo restituisce true
TypeDescriptor , per questo componente è possibile memorizzare nella cache i risultati.If this method returns true
, the TypeDescriptor for this component can cache the results. Questa cache viene mantenuta fino a quando il componente non viene sottoposta a Garbage Collection o viene chiamato il Refresh metodo del descrittore di tipo.This cache is maintained until either the component is garbage collected or the Refresh method of the type descriptor is called.
Note per gli implementatori
Per filtrare i descrittori di membro esposti da TypeDescriptorun, implementare questa interfaccia su un componente ed FilterAttributes(IComponent, IDictionary)eseguire l' FilterEvents(IComponent, IDictionary)override dei FilterProperties(IComponent, IDictionary) metodi, o di questa classe per filtrare rispettivamente attributi, eventi o proprietà.To filter the member descriptors exposed by a TypeDescriptor, implement this interface on a component and override the FilterAttributes(IComponent, IDictionary), FilterEvents(IComponent, IDictionary), or FilterProperties(IComponent, IDictionary) methods of this class to filter attributes, events, or properties, respectively.
Metodi
FilterAttributes(IComponent, IDictionary) |
Filtra gli attributi esposti da un componente tramite un oggetto TypeDescriptor.Filters the attributes that a component exposes through a TypeDescriptor. |
FilterEvents(IComponent, IDictionary) |
Filtra gli eventi esposti da un componente tramite un oggetto TypeDescriptor.Filters the events that a component exposes through a TypeDescriptor. |
FilterProperties(IComponent, IDictionary) |
Filtra le proprietà esposte da un componente tramite un oggetto TypeDescriptor.Filters the properties that a component exposes through a TypeDescriptor. |