.NET:如何知道序列化何时完成?

时间:2008-10-28 20:59:40

标签: .net winforms serialization

当我构造我的控件(继承DataGrid)时,我添加了特定的行和列。这在设计时非常有用。不幸的是,在运行时我在同一个构造函数中添加我的行和列,但随后DataGrid被序列化(在构造函数运行之后)添加更多行和列。

序列化完成后,我需要清除所有内容并重新初始化行和列。是否有一个受保护的方法可以覆盖以了解控件何时完成序列化?

当然,我宁愿不必在构造函数中完成工作,抛弃它,并在(潜在的)序列化之后再次执行。是否有一个首选事件相当于“立即设置自己”,因此无论我是否序列化,它都会被调用一次?


我所说的序列化来自表单的代码隐藏文件中的InitializeComponent()方法。

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
   ...
}

如果InitializeComponent是由Control定义的虚拟方法,那将是完美的,然后我可以覆盖它,然后在我调用base之后执行我的处理:

protected override void InitializeComponent()
{
    base.InitializeComponent();

    InitializeMe();
}

但它不是祖先方法,只在代码隐藏文件中声明。

我注意到InitializeComponent在各种控件上调用SuspendLayout和ResumeLayout。我认为它可以覆盖ResumeLayout,然后执行我的初始化:

public override void ResumeLayout()
{
   base.ResumeLayout();

   InitializeMe();
}

但是ResumeLayout不是虚拟的,所以就这样了。

还有想法吗?我不能成为第一个创建自定义控件的人。

2 个答案:

答案 0 :(得分:1)

似乎正在发生的事情是:

  1. 您设计了一个自定义DataGrid,它在构造函数
  2. 中添加了自己的行和列
  3. 您已将自定义DataGrid添加到表单
  4. 您发现表单设计器已在表单的InitializeComponent中编写代码,该代码会再次添加这些行和列
  5. Windows窗体设计器代码生成器的工作方式是查看所有对象的属性,确定默认值应该是什么,并为未设置为默认值的属性生成代码。不幸的是,DataGrid的默认状态是没有行而没有列。

    但是,您可以使用一组属性更改此行为。一种简单的方法可能是将Rows和Columns属性的新副本添加到您的类中,它只返回base.Rows和base.Columns。以这种方式添加重复属性允许您将DesignerSerializationVisibilty属性应用于它们,您可以使用这些属性强制表单设计器忽略预先填充的行和列。

答案 1 :(得分:0)

“是否有一个受保护的方法可以覆盖以了解控件何时完成序列化?”

不,不是受保护的方法,但有一个接口。如果您的控件实现ISupportInitialize,那么当Visual Studio下一次保存包含您的自定义控件的Form / UserControl的.designer.cs时,它会在您控制后立即自动添加对BeginInit方法的调用实例化(但在分配任何属性值之前),并在设置完所有属性后调用EndInit

然而,虽然这给你提供了很大的灵活性,但是对于你所描述的那种东西来说是正确的(我已经用它做了很多相同的事情,所以我知道)。如果您的后代完全控制行和列,并且用户在设计器中编辑它们永远不会有意义,那么Tim的建议(DesignerSerializationVisibility)会更简单,更容易实现。