这是设置:我已经创建了一个用户控件MyUserControl.在此控件上是一个简单的标签.当我在表单上删除此控件的新实例时,我希望标签是控件的名称.例如,如果这是控件的第一个实例,VStudio会自动将其名称设置为"myUserControl1".我只想把标签读作"myUserControl1".如果这是第五个控件,VStudio会将其命名为myUserControl5.我希望标签能够相应改变......但仅限于尚未设置的标签.一旦我将其设置为"标签",它应该保持不变.
我觉得这很容易.在构造函数中,设置label1.Text = this.Name.但后来我意识到,在实例化时,这个名字只是MyUserControl.它还没有被VisualStudio和CONTAINING InitializeComponent()方法命名.
啊! 我只是覆盖"名称"字段.设置完成后,检查DesignMode并更新标签!...但我无法覆盖名称.它不是虚拟的或抽象的.我可以使用"新"强制它,但是,它永远不会发射,从而击败目的.
我可以用哪个事件来表示设计师何时命名控件?我知道当他们放弃对窗体的控制时,redmond人会一直这样做,所以这很有可能.我实际上对这个小谜语感到很难过.
所以,这是最终的答案:
根据 Hans 的建议,它确实需要 ControlDesigner。我创建了一个简单的设计器,可以与一些内部属性交互,并且我确实让它工作了。不过,这里有一个问题:这有点像黑客。似乎没有一个字段具有我正在寻找的值,所以我必须对.ToString()一个对象执行 a 操作,然后解析出第一部分。我想这已经是最干净的了。
public class MyControlDesigner : ControlDesigner
{
public MyControlDesigner()
{
}
public override void InitializeNewComponent(IDictionary defaultValues)
{
base.InitializeNewComponent(defaultValues);
MyControl control1 = this.Component as MyControl;
control1.LabelText = control1.ToString().Split(" ".ToCharArray())[0];
}
}
Run Code Online (Sandbox Code Playgroud)
然后在 MyControl 的顶部,我简单地添加了一个新属性:
[DesignerAttribute(typeof(MyControlDesigner))]
public partial class MyControl : UserControl
{
...
// Using the property "Text" Causes Visual Studio to crash!!!
public string LabelText
{
get { return label1.Text; }
set { label1.Text = value; }
}
...
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它并不是很复杂,但有点 hack 式。当我尝试覆盖“Text”时,控件锁定了 IDE。不知道为什么,但当我将其称为“LabelText”时,它工作得很好。