ITypeDescriptorFilterService 인터페이스
디자인 모드에서 구성 요소에 대한 멤버 설명자의 집합을 수정할 수 있는 인터페이스를 제공합니다.
네임스페이스: System.ComponentModel.Design
어셈블리: System(system.dll)
구문
‘선언
Public Interface ITypeDescriptorFilterService
‘사용 방법
Dim instance As ITypeDescriptorFilterService
public interface ITypeDescriptorFilterService
public interface class ITypeDescriptorFilterService
public interface ITypeDescriptorFilterService
public interface ITypeDescriptorFilterService
설명
ITypeDescriptorFilterService 인터페이스는 디자인 타임에 구성 요소의 속성, 이벤트 및 클래스 수준 특성을 수정할 수 있도록 하는 인터페이스를 제공합니다. 구성 요소가 TypeDescriptor를 통해 제공하는 설명자 집합을 통해 수정이 발생합니다. 형식 설명자가 구성 요소의 사이트에 ITypeDescriptorFilterService 서비스를 쿼리하고, 서비스가 있으면 형식 설명자는 수집한 모든 메타데이터를 이 서비스에 전달합니다. 그러면 서비스에서 구성 요소의 기존 특징을 추가, 제거 및 변경하여 메타데이터를 수정할 수 있습니다.
예를 들어, FilterProperties 메서드를 호출하여 구성 요소의 속성을 수정할 수 있습니다. 필터 서비스는 PropertyDescriptor 형식의 속성 이름과 속성 설명자가 포함된 사전을 가져옵니다. 다음 논리를 사용하여 수정이 구현됩니다.
수정 |
구현 |
---|---|
제거 |
사전에 있는 해당 엔트리를 삭제합니다. |
추가 |
사전에 알맞은 엔트리를 추가합니다. |
변경 |
기존의 속성 설명자 메서드를 호출하거나, 연결된 속성 설명자 엔트리를 바꾸거나, 사전에 있는 전체 속성 키/값 쌍을 바꿉니다. |
FilterProperties의 반환 값에 따라 이 속성 집합의 고정 여부가 결정됩니다. 이 메서드가 true를 반환하면 이 구성 요소에 대한 TypeDescriptor가 결과를 캐시할 수 있습니다. 구성 요소가 가비지 수집되거나 형식 설명자의 Refresh 메서드가 호출될 때까지 이 캐시가 유지됩니다.
구현자 참고 사항 TypeDescriptor로 노출된 멤버 설명자를 필터링하려면 구성 요소에서 이 인터페이스를 구현하고 이 클래스의 FilterAttributes, FilterEvents 또는 FilterProperties 메서드를 재정의하여 특성, 이벤트 또는 속성을 각각 필터링합니다.
예제
다음 코드 예제에서는 신규 또는 기존 Button의 특성 컬렉션을 필터링할 ITypeDescriptorFilterService를 사용하여 해당 단추에 대해 디자이너를 로드하거나 다시 로드하기 전에 새 디자이너에 디자이너 특성을 추가하는 디자이너를 보여 줍니다.
이 예제를 사용하려면 Windows Forms 프로젝트에 코드를 추가하고 클래스 라이브러리에서 도구 상자로 구성 요소를 로드하십시오.
연습: 도구 상자에 자동으로 사용자 지정 구성 요소 채우기
연습: 도구 상자에 자동으로 사용자 지정 구성 요소 채우기
연습: 도구 상자에 자동으로 사용자 지정 구성 요소 채우기
연습: 도구 상자에 자동으로 사용자 지정 구성 요소 채우기
폼에 일부 단추를 추가합니다. 폼에 ButtonDesignerFilterComponent
를 추가하면 구성 요소 트레이에 나타납니다. ButtonDesignerFilterComponent
는 ITypeDescriptorFilterService를 구현하는 ButtonDesignerFilterService
를 디자인 모드 서비스 공급자로 추가합니다. 폼의 기존 또는 신규 Button 개체는 ButtonDesignerFilterService
가 각 기존 및 신규 단추에 대한 디자이너를 ColorCycleButtonDesigner
로 대체한 후 색 순환을 시작합니다. 해당 단추 위로 마우스를 이동하면 단추의 색이 순환되며 순환을 계속하거나 MouseLeave 이벤트에서 배경색과 전경색을 다시 설정합니다. ButtonDesignerFilterComponent
가 삭제되고 원래 ITypeDescriptorFilterService를 대체할 때까지 새 Button 개체는 로드된 ButtonDesignerFilterService
의 FilterAttributes 메서드를 통해 ColorCycleButtonDesigner
를 받습니다. 이 예제에서 ColorCycleButton
클래스는 ColorCycleButtonDesigner
와 관련된 Button입니다.
Imports System
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 'New
Public Sub New()
End Sub 'New
End Class 'ButtonDesignerFilterComponent
' 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 Not (tdfs Is 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 Not (oldservice Is 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 Not (oldService Is 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 Not (oldService Is 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 Not (oldService Is 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
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()
{}
}
}
#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(){}
};
package ITypeDescriptorFilterSample;
import System.*;
import System.Collections.*;
import System.ComponentModel.*;
import System.ComponentModel.Design.*;
import System.ComponentModel.Design.Serialization.*;
import System.Drawing.*;
import System.Reflection.*;
import System.Timers.*;
import System.Windows.Forms.*;
import System.Windows.Forms.Design.*;
// Component to host the ButtonDesignerFilterComponentDesigner that loads the
// ButtonDesignerFilterService ITypeDescriptorFilterService.
/** @attribute Designer(ButtonDesignerFilterComponentDesigner.class)
*/
public class ButtonDesignerFilterComponent
extends System.ComponentModel.Component
{
public ButtonDesignerFilterComponent(System.ComponentModel.
IContainer container)
{
container.Add(this);
} //ButtonDesignerFilterComponent
public ButtonDesignerFilterComponent()
{
} //ButtonDesignerFilterComponent
} //ButtonDesignerFilterComponent
// Provides a designer that can add a ColorCycleButtonDesigner to each
// button in a design time project using the ButtonDesignerFilterService
// ITypeDescriptorFilterService.
public class ButtonDesignerFilterComponentDesigner
extends System.ComponentModel.Design.ComponentDesigner
{
// Indicates whether the service has been loaded.
private boolean serviceLoaded = false;
// Stores any old ITypeDescriptorFilterService to restore later.
private ITypeDescriptorFilterService oldService = null;
public ButtonDesignerFilterComponentDesigner()
{
} //ButtonDesignerFilterComponentDesigner
// Loads the new ITypeDescriptorFilterService and reloads the
// designers for each button.
public void Initialize(System.ComponentModel.IComponent component)
throws Exception
{
super.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();
for(int iCtr = 0; iCtr < this.get_Component().get_Site().
get_Container().get_Components().get_Count(); iCtr++) {
IComponent c = this.get_Component().get_Site().get_Container().
get_Components().get_Item(iCtr);
if(c.GetType().Equals(System.Windows.Forms.
Button.class.ToType())) {
buttons.Add((System.Windows.Forms.Button)c);
}
}
if (buttons.get_Count() > 0) {
// Tests each Button for an existing
// ColorCycleButtonDesigner;
// if it has no designer of type
// ColorCycleButtonDesigner, adds a designer.
for (int iCtr=0; iCtr<buttons.get_Count(); iCtr++ ){
System.Windows.Forms.Button b =(System.Windows.
Forms.Button) buttons.get_Item(iCtr);
boolean loadDesigner = true;
// Gets the attributes for each button.
AttributeCollection ac = TypeDescriptor.GetAttributes(b);
for (int i = 0; i < ac.get_Count(); i++) {
// If designer attribute is not for a
// ColorCycleButtonDesigner, adds a new
// ColorCycleButtonDesigner.
if (ac.get_Item(i) instanceof DesignerAttribute) {
DesignerAttribute da = (DesignerAttribute)ac.
get_Item(i);
if (da.get_DesignerTypeName().Substring((da.
get_DesignerTypeName().LastIndexOf(".")+ 1)).
Equals("ColorCycleButtonDesigner")) {
loadDesigner = false;
}
}
}
if (loadDesigner) {
// Saves the button location so that it
// can be repositioned.
Point p = b.get_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(IMenuCommandService.class.ToType()));
if (imcs == null) {
throw new Exception("Could not obtain"
+ "ISelectionService interface.");
}
// Gets an ISelectionService to select the
// button so that it can be cut and pasted.
ISelectionService iss = (ISelectionService)this.
GetService(ISelectionService.class.ToType());
if (iss == null) {
throw new Exception("Could not obtain"
+ "ISelectionService interface.");
}
iss.SetSelectedComponents(new IComponent[] {b},
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 = (System.Windows.
Forms.Button)iss.get_PrimarySelection();
iss.SetSelectedComponents(null);
// Refreshes TypeDescriptor properties of
// button to load new attributes from
// ButtonDesignerFilterService.
TypeDescriptor.Refresh(b2);
b2.set_Location(p);
b2.Focus();
}
}
}
} //Initialize
// Loads a ButtonDesignerFilterService ITypeDescriptorFilterService
// to add ColorCycleButtonDesigner designers to each button.
private void LoadService() throws Exception
{
// If no custom ITypeDescriptorFilterService is loaded,
// loads it now.
if (!(serviceLoaded)) {
// Stores the current ITypeDescriptorFilterService
// to restore later.
ITypeDescriptorFilterService tdfs =
(ITypeDescriptorFilterService)(this.get_Component().get_Site().
GetService(ITypeDescriptorFilterService.class.ToType()));
if (tdfs != null) {
oldService = tdfs;
}
// Retrieves an IDesignerHost interface to use to
// remove and add services.
IDesignerHost dh = (IDesignerHost) this.get_Component().
get_Site().GetService(IDesignerHost.class.ToType());
if (dh == null) {
throw new Exception("Could not obtain IDesignerHost interface.");
}
// Removes standard ITypeDescriptorFilterService.
dh.RemoveService(ITypeDescriptorFilterService.class.ToType());
// Adds new custom ITypeDescriptorFilterService.
dh.AddService(ITypeDescriptorFilterService.class.ToType(),
new ButtonDesignerFilterService());
serviceLoaded = true;
}
} //LoadService
// Removes the custom service and reloads any stored,
// preexisting service.
private void RemoveService() throws Exception
{
IDesignerHost dh
= (IDesignerHost)(this.GetService(IDesignerHost.class.ToType()));
if (dh == null) {
throw new Exception("Could not obtain IDesignerHost interface.");
}
dh.RemoveService(ITypeDescriptorFilterService.class.ToType());
if (oldService != null) {
dh.AddService(ITypeDescriptorFilterService.
class.ToType(),oldService);
}
serviceLoaded = false;
} //RemoveService
protected void Dispose(boolean disposing) throws Exception
{
if (serviceLoaded) {
RemoveService();
}
} //Dispose
} //ButtonDesignerFilterComponentDesigner
// Provides a TypeDescriptorFilterService to add the
// ColorCycleButtonDesigner using a DesignerAttribute.
public class ButtonDesignerFilterService
implements System.ComponentModel.Design.ITypeDescriptorFilterService
{
public ITypeDescriptorFilterService oldService = null;
public ButtonDesignerFilterService()
{
} //ButtonDesignerFilterService
public ButtonDesignerFilterService(
ITypeDescriptorFilterService oldService_)
{
// Stores any previous ITypeDescriptorFilterService to implement
//service chaining.
this.oldService = oldService_;
} //ButtonDesignerFilterService
public boolean 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(ColorCycleButtonDesigner
.class.ToType());
// Adds the designer attribute if the attribute collection does not
//contain a DesignerAttribute of the same TypeID.
if (component instanceof System.Windows.Forms.Button
&& attributes.Contains(da.get_TypeId())) {
attributes.set_Item( da.get_TypeId(), da );
}
return true ;
} //FilterAttributes
public boolean FilterEvents(System.ComponentModel.IComponent component,
System.Collections.IDictionary events)
{
if (oldService != null) {
oldService.FilterEvents(component, events);
}
return true ;
} //FilterEvents
public boolean FilterProperties(System.ComponentModel.IComponent component,
System.Collections.IDictionary properties)
{
if (oldService != null) {
oldService.FilterProperties(component, properties);
}
return true ;
} //FilterProperties
} //ButtonDesignerFilterService
// Designer for a Button control which cycles the background color.
public class ColorCycleButtonDesigner
extends System.Windows.Forms.Design.ControlDesigner
{
private System.Windows.Forms.Timer timer1;
private Color initial_bcolor, initial_fcolor;
private int r, g, b;
private boolean ru, gu, bu, continue_;
public ColorCycleButtonDesigner()
{
timer1 = new System.Windows.Forms.Timer();
timer1.set_Interval(50);
timer1.add_Tick(new EventHandler(this.Elapsed));
ru = true;
gu = false;
bu = true;
continue_ = false;
timer1.Start();
} //ColorCycleButtonDesigner
private void Elapsed(Object sender, EventArgs e)
{
this.get_Control().set_BackColor(Color.FromArgb(r % 255,
g % 255, b % 255));
this.get_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.get_Control().set_ForeColor(Color.FromArgb((this.get_Control().
get_BackColor().get_R() + 128) % 255,(this.get_Control().
get_BackColor().get_G() + 128) % 255,(this.get_Control().
get_BackColor().get_B() + 128) % 255));
} //Elapsed
protected void OnMouseEnter()
{
if (!(timer1.get_Enabled())) {
initial_bcolor = this.get_Control().get_BackColor();
initial_fcolor = this.get_Control().get_ForeColor();
r = initial_bcolor.get_R();
g = initial_bcolor.get_G();
b = initial_bcolor.get_B();
timer1.Start();
}
} //OnMouseEnter
protected void OnMouseLeave()
{
if (!(continue_)) {
continue_ = true;
timer1.Stop();
}
else {
continue_ = false;
}
this.get_Control().set_BackColor(initial_bcolor);
this.get_Control().set_ForeColor(initial_fcolor);
} //OnMouseLeave
protected void Dispose(boolean disposing)
{
timer1.Stop();
this.get_Control().set_BackColor(initial_bcolor);
this.get_Control().set_ForeColor(initial_fcolor);
super.Dispose(disposing);
} //Dispose
} //ColorCycleButtonDesigner
// System.Windows.Forms.Button associated with the ColorCycleButtonDesigner.
/** @attribute Designer(ColorCycleButtonDesigner.class)
*/
public class ColorCycleButton extends System.Windows.Forms.Button
{
public ColorCycleButton()
{
} //ColorCycleButton
} //ColorCycleButton
플랫폼
Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
.NET Framework에서 모든 플래폼의 모든 버전을 지원하지는 않습니다. 지원되는 버전의 목록은 시스템 요구 사항을 참조하십시오.
버전 정보
.NET Framework
2.0, 1.1, 1.0에서 지원
참고 항목
참조
ITypeDescriptorFilterService 멤버
System.ComponentModel.Design 네임스페이스
TypeDescriptor 클래스
EventDescriptor 클래스
PropertyDescriptor 클래스
Attribute
IDictionary