我有一个自定义控件,其公共集合标记为DesignerSerializationVisibility.Content
。
当我使用设计器向集合中添加项目时,它会将它们添加到设计器文件并分配所有需要的值,但它会为集合的每个元素提供一个通用名称,例如MyClass1
,{{1}我希望每个项目的“Name”属性成为项目的代码名称,以便我可以在代码中按名称访问该项目。
这是ContextMenuStrip和ToolStrip如何工作的功能。在这些情况下,Name属性在属性网格中显示为MyClass2
。
是否有可用于获取此功能的属性或内容?或者我是否必须编写一个完整的自定义设计器对话框?如果是这样的话,我能做到这一点的最简单方法的例子是什么?
答案 0 :(得分:6)
您可以尝试从Component继承以获取该功能。
在这个例子中,我创建了一个名为PanelItem
的类,它将是我自己的Panel类在我的集合中使用的类。我添加了DesignTimeVisible(false)
,因此它不会填充设计器中的组件托盘。
另外,我添加了一个Name
属性,该属性对设计器是隐藏的,但可以在代码中使用。它似乎在我的测试中起作用:
[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;
}
}
}
然后我的自定义面板控件:
public class MyPanel : Panel {
private List<PanelItem> panelItems = new List<PanelItem>();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<PanelItem> PanelItems {
get { return panelItems; }
}
}
导致:
答案 1 :(得分:1)
我相信你的自定义控件本身需要一个DesignerSerializer,而仅使用DesignerSerializationVisibility.Content
来修饰集合是不够的。
我使用ILSpy来检查:ToolStrip将其DesignerSerializer设置为内部ToolStripCodeDomSerializer,我认为它负责生成所涉及的所有代码属性。
我认为实施这项工作将是一项专业工作。以下是MSDN文章:http://msdn.microsoft.com/en-us/library/ms171834.aspx。您正在寻找CodeDomSerializer的实现,我相信:http://msdn.microsoft.com/en-us/library/system.componentmodel.design.serialization.codedomserializer.aspx。