是否可以在设计器生成的代码中设置自定义 属性 或自定义 component/control 的序列化顺序?
Is it posible to set the order of the serialization of a custom property of a custom component/control in the designer-generated code?
我正在处理一些具有自定义属性的自定义(继承)控件,我在适当的属性修饰后为其添加了设计时支持。
一切正常,但我的问题是在使用控件的 *.Designer.cs 文件中自动生成的代码有一个特定的顺序,它在其中设置各种属性(包括基本属性和新属性)特性)。这个顺序看起来是按字母顺序排列的 w.r.t。 属性 名字。
因此自动生成的代码如下所示:
//
// myTabPage1
//
this.myTabPage1.Identifier = "ID";
this.myTabPage1.Name = "myTabPage1";
this.myTabPage1.Size = new System.Drawing.Size(294, 272);
this.myTabPage1.Text = "TTT";
我希望它看起来像这样:
//
// myTabPage1
//
this.myTabPage1.Name = "myTabPage1";
this.myTabPage1.Size = new System.Drawing.Size(294, 272);
this.myTabPage1.Text = "TTT";
this.myTabPage1.Identifier = "ID";
我需要这个的原因是因为设置 Identifier
属性 会影响 Text
然后恢复到它的设计时值,取消设置 Identifier
.
当然有一些简单的解决方法(最简单的方法是不设置文本 属性 效果很好),但如果这不是设计时就更好了 "worry",因为在许多继承的控件类型及其实例中广泛使用了这种设计模式。
设置 Text
也有助于识别表单设计器上的控件(Identifier
在设计时对 Text
没有影响)。
不,您不能影响序列化顺序。这是一个通用解决方案的常见问题,实施 ISupportInitialize interface。您的 BeginInit() 方法在设计人员开始分配属性之前被调用,您通常会设置一个 bool 变量以确保 属性 setter 不会产生意外的副作用.您的 EndInit() 方法在完成时被调用并且所有属性都有一个值,您将变量设置回 false 并做任何您需要做的事情来使用这些值。
您的问题对于有问题的控件不够具体,但可能的实现方式如下所示:
public partial class CustomControl : UserControl, ISupportInitialize {
public CustomControl() {
InitializeComponent();
}
private bool initializing;
private string id = "";
public string ID {
get { return id; }
set { id = value;
if (!initializing) label1.Text = value;
}
}
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text {
get { return base.Text; }
set {
base.Text = value;
if (!initializing && !this.DesignMode) label1.Text = value;
}
}
public void BeginInit() {
initializing = true;
}
public void EndInit() {
initializing = false;
label1.Text = ID;
}
}
另请注意此代码中的 [DesignerSerializationVisibility] 属性,当您使用 Hidden 时,属性 根本不会被序列化。这可能是您问题的简单解决方案。
我正在处理一些具有自定义属性的自定义(继承)控件,我在适当的属性修饰后为其添加了设计时支持。
一切正常,但我的问题是在使用控件的 *.Designer.cs 文件中自动生成的代码有一个特定的顺序,它在其中设置各种属性(包括基本属性和新属性)特性)。这个顺序看起来是按字母顺序排列的 w.r.t。 属性 名字。
因此自动生成的代码如下所示:
//
// myTabPage1
//
this.myTabPage1.Identifier = "ID";
this.myTabPage1.Name = "myTabPage1";
this.myTabPage1.Size = new System.Drawing.Size(294, 272);
this.myTabPage1.Text = "TTT";
我希望它看起来像这样:
//
// myTabPage1
//
this.myTabPage1.Name = "myTabPage1";
this.myTabPage1.Size = new System.Drawing.Size(294, 272);
this.myTabPage1.Text = "TTT";
this.myTabPage1.Identifier = "ID";
我需要这个的原因是因为设置 Identifier
属性 会影响 Text
然后恢复到它的设计时值,取消设置 Identifier
.
当然有一些简单的解决方法(最简单的方法是不设置文本 属性 效果很好),但如果这不是设计时就更好了 "worry",因为在许多继承的控件类型及其实例中广泛使用了这种设计模式。
设置 Text
也有助于识别表单设计器上的控件(Identifier
在设计时对 Text
没有影响)。
不,您不能影响序列化顺序。这是一个通用解决方案的常见问题,实施 ISupportInitialize interface。您的 BeginInit() 方法在设计人员开始分配属性之前被调用,您通常会设置一个 bool 变量以确保 属性 setter 不会产生意外的副作用.您的 EndInit() 方法在完成时被调用并且所有属性都有一个值,您将变量设置回 false 并做任何您需要做的事情来使用这些值。
您的问题对于有问题的控件不够具体,但可能的实现方式如下所示:
public partial class CustomControl : UserControl, ISupportInitialize {
public CustomControl() {
InitializeComponent();
}
private bool initializing;
private string id = "";
public string ID {
get { return id; }
set { id = value;
if (!initializing) label1.Text = value;
}
}
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text {
get { return base.Text; }
set {
base.Text = value;
if (!initializing && !this.DesignMode) label1.Text = value;
}
}
public void BeginInit() {
initializing = true;
}
public void EndInit() {
initializing = false;
label1.Text = ID;
}
}
另请注意此代码中的 [DesignerSerializationVisibility] 属性,当您使用 Hidden 时,属性 根本不会被序列化。这可能是您问题的简单解决方案。