元数据筛选

更新:2007 年 11 月

元数据筛选允许设计器在设计时修改组件或控件所公开的属性 (Property)、属性 (Attribute) 和事件。

例如,Control 具有一个名为 Visible 的属性 (Property),该属性 (Property) 确定控件是否可见。但是,无论该属性 (Property) 的值是多少,设计时控件总是应保持可见,以便开发人员可以在设计图面上定位它。Control 的设计器在设计时用自己的版本替换 Visible 属性 (Property),以后再恢复此属性 (Property) 的运行时值。

若要执行元数据筛选,设计器可以实现 IDesignerFilter 接口,或者可以向设计时服务提供程序(该程序可在设计时环境中对任何组件执行元数据筛选)添加 ITypeDescriptorFilterService 实现。

如果在设计时选中了某个组件,属性 (Property) 浏览器会通过 TypeDescriptor 的方法来查询该组件的属性 (Attribute)、事件和属性 (Property)。在设计模式下查询组件的属性 (Attribute)、事件和属性 (Property) 时,任何实现 IDesignerFilter 接口的组件的设计器都有机会修改该组件返回的属性 (Attribute)、事件和属性 (Property) 的集合。任何活动 ITypeDescriptorFilterService 的方法随后都会被调用,这样,服务就可以随意筛选属性 (Attribute)、事件和属性 (Property)。

在对组件调用 TypeDescriptorRefresh 方法时,在刷新“属性”窗口时,在建立或重新建立设计模式时,以及在设置主选项内容时,通常都会查询设计模式中组件的属性 (Attribute)、事件和属性 (Property)。其他对象或设计时环境的方法可以在其他时间调用 TypeDescriptor 的方法。

组件元数据筛选的 IDesignerFilter 接口

IDesignerFilter 接口定义了一组能够在设计器中重写和实现的方法,以更改设计器所管理的组件在设计时公开的属性 (Property)、事件或属性 (Attribute)。

IDesignerFilter 接口的每一个方法都以“Pre”或“Post”作为前缀。根据允许添加、更改或移除的成员类型的不同,每一方法以“Attributes”、“Events”或“Properties”作为后缀。要添加任何属性 (Attribute)、事件或属性 (Property),使用名称以“Pre”开头的相关方法。要更改或移除任何属性 (Attribute)、事件或属性 (Property),使用名称以“Post”开头的相关方法。以“Pre”开头的方法在紧靠名称以“Post”开头的方法之前调用。

如果您要添加一个或多个属性,可实现对 PreFilterAttributes 方法的重写,该方法将新 System.Attribute 添加到传递给该方法的 IDictionary。字典中的关键字是属性 (Attribute) 的类型 ID。若要更改或移除一个或多个属性,可实现对 PostFilterAttributes 方法的重写。

如果您要添加一个或多个事件,可实现对 PreFilterEvents 方法的重写,该方法将新 EventDescriptor 添加到传递给该方法的 IDictionary。字典中的关键字是事件的名称。若要更改或移除一个或多个事件,可实现对 PostFilterEvents 方法的重写。

如果您要添加一个或多个属性,可实现对 PreFilterProperties 方法的重写,该方法将新 PropertyDescriptor 添加到传递给该方法的 IDictionary。字典中的关键字是属性 (Property) 的名称。若要更改或移除一个或多个属性,可实现对 PostFilterProperties 方法的重写。

说明:

当类对实现 IDesignerFilter 的设计器进行扩展时,每个 PostMethodName 方法应在更改自己的属性 (Attribute) 之后调用基类中相应的 PostMethodName 方法,每个 PreMethodName 方法应在更改自己的属性 (Attribute) 之前调用基类中相应的 PreMethodName 方法。

下面的代码示例块说明了 IDesignerFilter 接口的方法签名。

Public Interface IDesignerFilter
   Sub PostFilterAttributes(attributes As IDictionary)
   Sub PostFilterEvents(events As IDictionary)
   Sub PostFilterProperties(properties As IDictionary)
   Sub PreFilterAttributes(attributes As IDictionary)
   Sub PreFilterEvents(events As IDictionary)
   Sub PreFilterProperties(properties As IDictionary)
End Interface
public interface IDesignerFilter {
    void PostFilterAttributes(IDictionary attributes);
    void PostFilterEvents(IDictionary events);
    void PostFilterProperties(IDictionary properties);
    void PreFilterAttributes(IDictionary attributes);
    void PreFilterEvents(IDictionary events);
    void PreFilterProperties(IDictionary properties);
}

下面的代码示例演示 IDesignerFilter 的实现,这一实现将设计器的 Color 属性添加到关联的组件中。

Imports System
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Windows.Forms.Design

Namespace IDesignerFilterSample
 _
    Public Class DesignerFilterDesigner
        Inherits ComponentDesigner        

        ' Designer color property to add to component.
        Public Property TestColor() As Color
            Get
                Return Me.intcolor
            End Get
            Set(ByVal Value As Color)
                Me.intcolor = Value
            End Set
        End Property

        ' Color for TestColor property.
        Private intcolor As Color = Color.Azure

        Public Function DesignerFilterDesigner()
        End Function 'DesignerFilterDesigner

        ' Adds a color property of this designer to the component.
        Protected Overrides Sub PreFilterProperties(ByVal properties As System.Collections.IDictionary)
            MyBase.PreFilterProperties(properties)
            ' Adds a test property to the component.
            properties.Add("TestColor", TypeDescriptor.CreateProperty(GetType(DesignerFilterDesigner), "TestColor", GetType(System.Drawing.Color), Nothing))
        End Sub 'PreFilterProperties

    End Class 'DesignerFilterDesigner

    ' Component with which the DesignerFilterDesigner is associated.
    <Designer(GetType(DesignerFilterDesigner))>  _    
    Public Class TestComponent
        Inherits Component

        Public Function TestComponent()
        End Function 'TestComponent
    End Class 'TestComponent

End Namespace
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace IDesignerFilterSample
{
   public class DesignerFilterDesigner : ComponentDesigner, IDesignerFilter
   {
      // Designer color property to add to component.
      public Color TestColor
      {
         get
         { return this.intcolor;   }
         set
         { this.intcolor = value; }
      }

      // Color for TestColor property.
      private Color intcolor = Color.Azure;

      public DesignerFilterDesigner()
      {}

      // Adds a color property of this designer to the component.
      protected override void PreFilterProperties(System.Collections.IDictionary properties)
      {
         base.PreFilterProperties(properties);
         // Adds a test property to the component.
         properties.Add("TestColor", TypeDescriptor.CreateProperty(typeof(DesignerFilterDesigner), "TestColor", typeof(System.Drawing.Color), null));
      }
   }

   // Component with which the DesignerFilterDesigner is associated.
   [Designer(typeof(DesignerFilterDesigner))]
   public class TestComponent : Component
   {
      public TestComponent()
      {}
   }
}

有关使用 IDesignerFilter 接口实现属性筛选的“Windows 窗体”控件设计器的示例,请参见 Windows 窗体设计器示例

全局设计模式元数据筛选的 ITypeDescriptorFilterService

通过向可在设计时提供服务的服务提供程序中添加 ITypeDescriptorFilterService 实现,可为设计时项目中的任何组件提供元数据筛选,具体方法是使用设计模式中 ComponentSite 属性返回的 ISite 所实现的 IServiceContainer 接口的 AddService 方法。

下面的代码示例演示如何添加称为 ExampleFilterService 的 ITypeDescriptorFilterService 服务。

IDesignerHost dh = (IDesignerHost)this.Component.GetService(typeof(IDesignerHost));
if( dh != null )
{
   // First gets any previous ITypeDescriptorFilterService to replace when 
   // the current service is removed, and to call if the new service 
   // implements service chaining.
   ITypeDescriptorFilterService itdfs = 
   (ITypeDescriptorFilterService)dh.GetService(    typeof(ITypeDescriptorFilterService));
   
   oldService = (ITypeDescriptorFilterService)dh.GetService(
   typeof(ITypeDescriptorFilterService));
         
   if(oldService != null)
      // Removes any old ITypeDescriptorFilterService.
      dh.RemoveService(typeof(ITypeDescriptorFilterService));
         
   // Adds an ExampleFilterService that implements service chaining.
   dh.AddService(typeof(ITypeDescriptorFilterService), 
   new ExampleFilterService(oldService));
}

有关 ITypeDescriptorFilterService 实现的示例,请参见 ITypeDescriptorFilterService 类的参考文档。

请参见

任务

如何:在设计模式下调整组件的属性 (Attribute)、事件及属性 (Property)

概念

基设计器类

设计器谓词

如何:实现控件的设计器

类型说明符概述

其他资源

自定义设计器