Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User Control as container at design time

Tags:

I'm designing a simple expander control.

I've derived from UserControl, drawn inner controls, built, run; all ok.

Since an inner Control is a Panel, I'd like to use it as container at design time. Indeed I've used the attributes:

[Designer(typeof(ExpanderControlDesigner))] [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]  

Great I say. But it isn't...

The result is that I can use it as container at design time but:

  • The added controls go back the inner controls already embedded in the user control
  • Even if I push to top a control added at design time, at runtime it is back again on controls embedded to the user control
  • I cannot restrict the container area at design time into a Panel area

What am I missing? Here is the code for completeness... why this snippet of code is not working?

[Designer(typeof(ExpanderControlDesigner))] [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]  public partial class ExpanderControl : UserControl {     public ExpanderControl()     {         InitializeComponent(); ....  [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]  internal class ExpanderControlDesigner : ControlDesigner {     private ExpanderControl MyControl;      public override void Initialize(IComponent component)     {         base.Initialize(component);          MyControl = (ExpanderControl)component;          // Hook up events         ISelectionService s = (ISelectionService)GetService(typeof(ISelectionService));         IComponentChangeService c = (IComponentChangeService)GetService(typeof(IComponentChangeService));          s.SelectionChanged += new EventHandler(OnSelectionChanged);         c.ComponentRemoving += new ComponentEventHandler(OnComponentRemoving);     }      private void OnSelectionChanged(object sender, System.EventArgs e)     {      }      private void OnComponentRemoving(object sender, ComponentEventArgs e)     {      }      protected override void Dispose(bool disposing)     {         ISelectionService s = (ISelectionService)GetService(typeof(ISelectionService));         IComponentChangeService c = (IComponentChangeService)GetService(typeof(IComponentChangeService));          // Unhook events         s.SelectionChanged -= new EventHandler(OnSelectionChanged);         c.ComponentRemoving -= new ComponentEventHandler(OnComponentRemoving);          base.Dispose(disposing);     }      public override System.ComponentModel.Design.DesignerVerbCollection Verbs     {         get         {             DesignerVerbCollection v = new DesignerVerbCollection();              v.Add(new DesignerVerb("&asd", new EventHandler(null)));              return v;         }     } } 

I've found many resources (Interaction, designed, limited area), but nothing was usefull for being operative...

Actually there is a trick, since System.Windows.Forms classes can be designed (as usual) and have a correct behavior at runtime (TabControl, for example).

like image 885
Luca Avatar asked Apr 22 '10 22:04

Luca


People also ask

How do you define user control?

User controls are containers into which you can put markup and Web server controls. You can then treat the user control as a unit and define properties and methods for it. Custom controls. A custom control is a class that you write that derives from Control or WebControl.

What is one advantage of creating a form with custom controls?

This allows your control to contain other controls, and it gives your control a great deal of default functionality. Your custom control will have an associated custom designer. This allows you to create a unique design experience tailored specifically for your custom control.


1 Answers

ParentControlDesigner doesn't know what you want do. It only knows you want your UserControl to be a container.

What you need to do is implement your own designer which enables design mode on the panel:

    using System.ComponentModel;     using System.Windows.Forms;     using System.Windows.Forms.Design;      namespace MyCtrlLib     {         // specify my custom designer         [Designer(typeof(MyCtrlLib.UserControlDesigner))]         public partial class UserControl1 : UserControl         {             public UserControl1()             {                 InitializeComponent();             }              // define a property called "DropZone"             [Category("Appearance")]             [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]              public Panel DropZone             {                 get { return panel1; }             }         }          // my designer         public class UserControlDesigner  : ParentControlDesigner         {             public override void Initialize(System.ComponentModel.IComponent component)             {                 base.Initialize(component);                  if (this.Control is UserControl1)                 {                     this.EnableDesignMode(                        (UserControl1)this.Control).DropZone, "DropZone");                 }             }         }     } 

I learned this from Henry Minute on CodeProject. See the link for some improvements on the technique.

like image 190
Igby Largeman Avatar answered Sep 24 '22 06:09

Igby Largeman