自己开发窗体设计器----转载 刘志波 译

Shawn Burke
微软公司

2001年6月

英文原稿
《Writing Custom Designers for .NET Components》
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/custdsgnrdotnet.asp

刘志波 译
2001年12月

摘要:这篇文章包括了设计器的各种特性,如何把他们和组件关联起来,如何使用这些特性来创造更强的设计时期用户界面。

内容:
简介
什么是设计器?
组件如何和设计器关联?
修改设计时期的状态信息
定义组件之间的关系
使用组件自己的设计器来更改组件的属性、特性、事件
简化通常要做的工作
与其他组件精确的交互
结论

简介

什么是设计器?

public interface IDesigner : IDisposable {
        IComponent Component {get;}        
        DesignerVerbCollection Verbs {get;}
        void DoDefaultAction();
        void Initialize(IComponent component);
}

 

组件如何和设计器关联?

namespace MyCompany {
[Designer("MyCompany.Design.SysComponentDesigner, MyCompany.Design")]
public class SysComponent : Component {
}
}
namespace MyCompany.Design {
   internal class SysComponentDesigner : ComponentDesigner {
      // …
}
}

namespace MyCompany {
[Designer(typeof(SysComponentDesigner))]
public class SysComponent : Component {
   
internal class SysComponentDesigner : ComponentDesigner{
// …
}
}
}

public DesignerVerbCollection GetComponentVerbs(IComponent comp) {
        if (comp.Site != null){
            IDesignerHost host;
            host = comp.Site.GetService(typeof(IDesignerHost));
            if (host != null){
                IDesigner designer;
                designer = host.GetDesigner(comp);
                if (designer != null){
                    return designer.Verbs;
                }
            }
        }
        return new DesignerVerbCollection();
}
修改设计时期的状态信息

public class DragDropControlDesigner : ControlDesigner {
      public override void Initialize(IComponent c) {
         base.Initialize(c);
         ((Control)c).AllowDrop = false;
      }
   }

定义组件之间的关系

[Designer(typeof(MainComp.MainCompDesigner))]
public class MainComp : Component {

   public SubCompCollection SubComponents {
      get {   
         return subCollection;
      }
   }

   internal class MainCompDesigner : ComponentDesigner {
      public override ICollection AssociatedComponents{
         get{
            return ((MainComp)base.Component).SubComponents;
         }
      }
   }
}

[DesignTimeVisible(false)]
[Designer(typeof(SubComp.SubCompDesigner))]
public class SubComp : Component {
   public SubCompCollection SubSubComponents {
      get {   
         return subCollection;
      }
   }
   internal class SubCompDesigner : ComponentDesigner {

      public override ICollection AssociatedComponents{
         get{
            // Only return sited subs in this case.  
            // For example, this component could have 
            // a number of sub components that were 
            // added by the component and aren't sited 
            // on the design surface.  We don't want 
            // to move those around.
            //
            ArrayList comps = new ArrayList();
            foreach (SubComp sc in 
               ((SubComp)Component).SubSubComponents) {
               if (sc.Site != null) {
                  comps.Add(sc);
               }
            }
            return comps;
         }
      }
   }
}
使用组件自己的设计器来更改组件的属性、特性、事件

public class SimpleControlDesigner : ComponentDesigner {

   bool locked;

   public bool Enabled {
      get {
         return (bool)ShadowProperties["Enabled"];
      }
      set {
         // note this value is not passed to the actual
         // control
         this.ShadowProperties["Enabled"] = value;
      }
   }
   private bool Locked {
      get {
         return locked;
      }
      set {
         locked = value;            
      }
   }

   public bool Visible {
      get {
         return (bool)ShadowProperties["Visible"];
      }
      set {
         // note this value is not passed to the actual
         // control
         this.ShadowProperties["Visible"] = value;
      }
   }

   public void Initialize(IComponent c) {
      base.Initialize(c);
      Control control = c as Control;

      if (control == null) {
         throw new ArgumentException();
      }

      // pick up the current state and push it
      // into our shadow props to initialize them.
      //
      this.Visible = control.Visible;
      this.Enabled = control.Enabled;

      control.Visible = true;
      control.Enabled = true;
   }

protected override void PreFilterProperties(IDictionary properties) {
        base.PreFilterProperties(properties);
        
      // replace Visible and Enabled with our shadowed versions.
      //
      properties["Visible"] = TypeDescriptor.CreateProperty(
               typeof(SimpleControlDesigner), 
               (PropertyDescriptor)properties["Visible"], 
               new Attribute[0]);
      properties["Enabled"] = TypeDescriptor.CreateProperty(
               typeof(SimpleControlDesigner), 
               (PropertyDescriptor)properties["Enabled"], 
               new Attribute[0]);

      // and add the Locked property
      //
      properties["Locked"] = TypeDescriptor.CreateProperty(
               typeof(SimpleControlDesigner), 
               "Locked", 
               typeof(bool), 
               CategoryAttribute.Design, 
               DesignOnlyAttribute.Yes);
      }
}

简化通常要做的工作

[Designer(typeof(ColorButton.ColorButtonDesigner))]
   public class ColorButton : System.Windows.Forms.Button
   {
       internal class ColorButtonDesigner : ControlDesigner {
         private DesignerVerbCollection verbs = null;

    private void OnVerbRed(object sender, EventArgs e) {
         Control.BackColor = Color.Red;
      }

      private void OnVerbGreen(object sender, EventArgs e){
         Control.BackColor = Color.Green;
      }

      private void OnVerbBlue(object sender, EventArgs e) {
         Control.BackColor = Color.Blue;
      }

      public override DesignerVerbCollection Verbs {
         get {
           if (verbs == null) {
            verbs = new DesignerVerbCollection();
            verbs.Add( new DesignerVerb(
                         "Red", 
                         new EventHandler(OnVerbRed)));
            verbs.Add( new DesignerVerb(
                         "Blue", 
                         new EventHandler(OnVerbBlue)));
            verbs.Add( new DesignerVerb(
                         "Green", 
                         new EventHandler(OnVerbGreen)));
             }
           return verbs;
         }
      }
      }
   }
与其他组件精确的交互

private void OnVerbGreen(object sender, EventArgs e){
PropertyDescriptor backColorProp = 
      TypeDescriptor.GetProperties(Control)["BackColor"];
   
   if (backColorProp != null) {
      backColorProp.SetValue(Control, Color.Green);
}
}

internal class RadioButtonDesigner : ControlDesigner {

   public bool Checked  {
      get {
         // pass the get down to the control.
         //
         return ((RadioButton)Control).Checked;
      }
      set {
         // set the value into the control
         //
         ((RadioButton)Control).Checked = value;

         // if the value for this radio button
         // was set to true, notify that others have changed.
         //
         if (value) {
            IComponentChangeService ccs = 
               (IComponentChangeService)
            GetService(typeof(IComponentChangeService));
            if (ccs != null) {
               PropertyDesciptor checkedProp = 
                   TypeDescriptor.GetProperties(typeof(RadioButton))["Checked"];
               foreach(RadioButton rb in 
                  Control.Parent.Controls) {
                  if (rb == Control || !(rb is RadioButton)) 
continue;
                  
                  ccs.OnComponentChanging(rb, checkedProp);
                  ccs.OnComponentChanged(rb,chedkedProp, null, null);
               }
            }
         }
      }
   }

   protected override void PreFilterProperties(
                     IDictionary properties) {
      base.PreFilterProperties(properties);
      // shadow the checked property so we can intercept the set.
      //
      properties["Checked"] = 
TypeDescriptor.CreateProperty(               typeof(RadioButtonDesigner), 
               (PropertyDescriptor)properties["Checked"], 
               new Attribute[0]);
   }
}
结论
设计器可以给任何实现IComponent的对象编写并且驻扎(sited)在设计界面上。这对Windows Forms Controls、Web Form Controls和其他的组件来说都是适用的。给组件订制的设计器可以有不同于标准的设计界面而且可以让设计时期代码和执行时期代码分离,减少发布文件大小而且可以更强的控制组件的设计期行为。
从扩展性能上说,从.NET框架的设计时期接口和类导出的对象有能力订制自己的设计期行为,而以前的框架没有这些。运用这些能力来扩展组件就可以有更加丰富的设计期行为和运行期对象模型。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值