MSDN-元数据筛选

http://msdn.microsoft.com/zh-cn/library/tbt775x3(v=vs.100).aspx

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

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

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

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

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

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

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

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

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

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

注意注意

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

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

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 属性添加到关联的组件中。需要添加对 System.Design.dll 的引用。
C#VB
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 实现,可为设计时项目中的任何组件提供元数据筛选,具体方法是使用设计模式中Component 的 Site 属性返回的 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));
}

 

posted @ 2013-03-24 12:03  C#老头子  Views(391)  Comments(0Edit  收藏  举报