是否可以在设计器生成的代码中设置自定义 属性 或自定义 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 时,属性 根本不会被序列化。这可能是您问题的简单解决方案。