Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto-generate the code-behind name of designer collection items

I have a custom control with a public collection marked as DesignerSerializationVisibility.Content.

When I add items to the collection using the designer, it adds them to the designer file and assigns all desired values but it gives each element of the collection a generic name, such as MyClass1, MyClass2, etc. I want the "Name" property of each item to become the code name of the item so that I can then access the item by its name in code.

This is the functionality of how a ContextMenuStrip and ToolStrip works. In those cases, the Name property shows up as (Name) in the property grid.

Is there an attribute or something I can use to gain this functionality? Or do I have to write a whole custom designer dialog? If so, what's an example of the simplest way I could go about achieving this?

like image 833
Trevor Elliott Avatar asked Jun 13 '12 19:06

Trevor Elliott


2 Answers

You can try inheriting from Component to get that feature.

In this example, I created a class called PanelItem, which will be the class used in my collection by my own Panel class. I added DesignTimeVisible(false) so that it doesn't populate the component tray in the designer.

Also, I added a Name property that is hidden from the designer but can be used in code. It seemed to work in my tests:

[DesignTimeVisible(false)]
public class PanelItem : Component  {

  [DefaultValue(typeof(string), "")]
  public string PanelText { get; set; }

  private string name = string.Empty;

  [Browsable(false)]
  [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
  public string Name {
    get {
      if (base.Site != null) {
        name = base.Site.Name;
      }
      return name;
    }
    set {
      name = value;
    }
  }
}

Then my custom panel control:

public class MyPanel : Panel {
  private List<PanelItem> panelItems = new List<PanelItem>();

  [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  public List<PanelItem> PanelItems {
    get { return panelItems; }
  }
}

Resulted in:

enter image description here

like image 124
LarsTech Avatar answered Sep 28 '22 06:09

LarsTech


I believe your custom control itself is going to require a DesignerSerializer, and that merely decorating the collection with the the DesignerSerializationVisibility.Content will not be sufficient.

I used ILSpy to check: ToolStrip has its DesignerSerializer set to an internal ToolStripCodeDomSerializer, which I think is responsible for generating all the code properties involved.

I think implementing this will be a bit of specialized work. Here's the MSDN article to get you started: http://msdn.microsoft.com/en-us/library/ms171834.aspx. You're looking for an implementation of the CodeDomSerializer, I believe: http://msdn.microsoft.com/en-us/library/system.componentmodel.design.serialization.codedomserializer.aspx.

like image 26
Alan McBee Avatar answered Sep 28 '22 08:09

Alan McBee