当我构造我的控件(继承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不是虚拟的,所以就这样了。
还有想法吗?我不能成为第一个创建自定义控件的人。
答案 0 :(得分:1)
似乎正在发生的事情是:
Windows窗体设计器代码生成器的工作方式是查看所有对象的属性,确定默认值应该是什么,并为未设置为默认值的属性生成代码。不幸的是,DataGrid的默认状态是没有行而没有列。
但是,您可以使用一组属性更改此行为。一种简单的方法可能是将Rows和Columns属性的新副本添加到您的类中,它只返回base.Rows和base.Columns。以这种方式添加重复属性允许您将DesignerSerializationVisibilty属性应用于它们,您可以使用这些属性强制表单设计器忽略预先填充的行和列。
答案 1 :(得分:0)
“是否有一个受保护的方法可以覆盖以了解控件何时完成序列化?”
不,不是受保护的方法,但有一个接口。如果您的控件实现ISupportInitialize,那么当Visual Studio下一次保存包含您的自定义控件的Form / UserControl的.designer.cs时,它会在您控制后立即自动添加对BeginInit方法的调用实例化(但在分配任何属性值之前),并在设置完所有属性后调用EndInit。
然而,虽然这给你提供了很大的灵活性,但是对于你所描述的那种东西来说是正确的(我已经用它做了很多相同的事情,所以我知道)。如果您的后代完全控制行和列,并且用户在设计器中编辑它们永远不会有意义,那么Tim的建议(DesignerSerializationVisibility)会更简单,更容易实现。