ITypeDescriptorFilterService ITypeDescriptorFilterService ITypeDescriptorFilterService ITypeDescriptorFilterService Interface

定義

デザイン モードでコンポーネントの一連のメンバー記述子を変更するためのインターフェイスを提供します。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
派生

次のコード例に示しますを使用するデザイナー、 ITypeDescriptorFilterService 、新規または既存の属性のコレクションをフィルター処理するButton読み込みまたはボタンのデザイナーを再読み込みする前に新しいデザイナーのデザイナーの属性を追加します。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.

例を使用するには、Windows フォーム プロジェクトにコードを追加およびクラス ライブラリからツールボックスにコンポーネントを読み込みます。To use the example, add the code to a Windows Forms project and load the components from the class library into the Toolbox.

チュートリアル: カスタム コンポーネントでツールボックスが自動的に入力します。Also see Walkthrough: Automatically Populating the Toolbox with Custom Components.

いくつかのボタンをフォームに追加します。Add some buttons to your form. 追加、ButtonDesignerFilterComponentをフォームにして、コンポーネント トレイに表示されます。Add a ButtonDesignerFilterComponent to your form, and it will appear in the component tray. ButtonDesignerFilterComponentは追加、 ButtonDesignerFilterService、実装するITypeDescriptorFilterService、デザイン モードのサービス プロバイダーとして。The ButtonDesignerFilterComponent will add a ButtonDesignerFilterService, which implements ITypeDescriptorFilterService, as a design mode service provider. 既存または新規Button、フォーム上のオブジェクトが循環後に色を開始、ButtonDesignerFilterServiceで各既存および新規のボタンのデザイナーを置き換える、ColorCycleButtonDesignerします。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. 色のボタンがサイクルと、マウス ポインターを移動、およびまたは繰り返しを続行またはリセットした前景色および背景色でMouseLeaveイベント。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. 新しいButtonオブジェクトが与えられます、ColorCycleButtonDesignerを通じて、FilterAttributesのメソッド、ButtonDesignerFilterServiceするまで、読み込まれた、ButtonDesignerFilterComponentが破棄され、元の置換ITypeDescriptorFilterServiceします。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. ColorCycleButtonクラスがこの例では、Buttonに関連付けられている、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
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 (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 

注釈

ITypeDescriptorFilterServiceインターフェイスのデザイン時に、プロパティ、イベント、およびコンポーネントのクラス レベルの属性の変更を許可するインターフェイスを提供します。The ITypeDescriptorFilterService interface provides an interface that allows modification of the properties, events, and class-level attributes of a component at design time. コンポーネントを提供する記述子のセットをこの変更が発生した、TypeDescriptorします。This modification occurs through the set of descriptors that a component provides through a TypeDescriptor. 型記述子がコンポーネントのサイトのクエリを実行、ITypeDescriptorFilterServiceサービスし、型記述子がこのサービスには収集したすべてのメタデータを渡す、存在する場合。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. サービスは、追加、削除、およびコンポーネントの既存の特性を変更して、メタデータを変更できます。The service can then modify the metadata by adding, removing, and altering existing characteristics of the component.

呼び出すことによって、コンポーネントのプロパティを変更するなど、FilterPropertiesメソッド。For example, the properties of a component can be modified through a call to the FilterProperties method. フィルター サービスは、プロパティ名と型の場合は、そのプロパティ記述子を格納しているディクショナリを取得します。PropertyDescriptorします。The filter service obtains a dictionary that contains property names and their property descriptors of type PropertyDescriptor. 変更を実装するには、次のロジックを使用します。The modifications are implemented using the following logic.

変更Modification 実装Implementation
削除Removal ディクショナリ内の対応するエントリを削除します。Delete the corresponding entry in the dictionary.
加算Addition ディクショナリに適切なエントリを追加します。Add the appropriate entry to the dictionary.
変更を加えるAlteration プロパティ記述子の既存のメソッドを呼び出して、関連付けられているプロパティの記述子のエントリを置換、またはディクショナリ内全体のプロパティのキー/値ペアを置き換えます。Call existing property descriptor methods, replace the associated property descriptor entry, or replace the entire property key/value pair in the dictionary.

戻り値FilterPropertiesこの一連のプロパティは固定されているかどうかを決定します。The return value of FilterProperties determines if this set of properties is fixed. このメソッドが戻る場合trueTypeDescriptorのこのコンポーネントは、結果をキャッシュできます。If this method returns true, the TypeDescriptor for this component can cache the results. このキャッシュが、いずれかのコンポーネントがガベージ コレクションされるまで保持されます。 または、Refresh型記述子のメソッドが呼び出されます。This cache is maintained until either the component is garbage collected or the Refresh method of the type descriptor is called.

注意 (実装者)

によって公開されるメンバー記述子をフィルター処理する、 TypeDescriptor、コンポーネントでこのインターフェイスを実装し、上書き、 FilterAttributes(IComponent, IDictionary)FilterEvents(IComponent, IDictionary)、またはFilterProperties(IComponent, IDictionary)をそれぞれの属性、イベント、またはプロパティをフィルター処理するには、このクラスのメソッド。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.

メソッド

FilterAttributes(IComponent, IDictionary) FilterAttributes(IComponent, IDictionary) FilterAttributes(IComponent, IDictionary) FilterAttributes(IComponent, IDictionary)

TypeDescriptor を通じてコンポーネントが公開する属性をフィルター処理します。Filters the attributes that a component exposes through a TypeDescriptor.

FilterEvents(IComponent, IDictionary) FilterEvents(IComponent, IDictionary) FilterEvents(IComponent, IDictionary) FilterEvents(IComponent, IDictionary)

TypeDescriptor を通じてコンポーネントが公開するイベントをフィルター処理します。Filters the events that a component exposes through a TypeDescriptor.

FilterProperties(IComponent, IDictionary) FilterProperties(IComponent, IDictionary) FilterProperties(IComponent, IDictionary) FilterProperties(IComponent, IDictionary)

TypeDescriptor を通じてコンポーネントが公開するプロパティをフィルター処理します。Filters the properties that a component exposes through a TypeDescriptor.

適用対象

こちらもご覧ください