編寫組件自己的設計器

專欄作品

 

編寫組件自己的設計器
劉志波


簡介

什麼是設計器?

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]);

   }

}

結論

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章