我有代码可以根据需要动态加载(并销毁)不同类型的用户控件到表单上。用户控件使用其父级的属性将某些值加载到控件(如文本框和复选框)中。问题在于:
activeControl = new userControl1(params...);
我的构造函数显然会尝试加载尚不存在的字段(它们属于父窗体),因为在创建userControl1之前它尚未添加到父窗体中。
我尝试使用用户控件的ParentChanged事件解决此问题,因此它会等到其父项在加载字段之前设置为止。这里的问题是当我销毁userControl1并创建一个userControl2时,父更改并尝试从null ParentForm加载字段(我原来的确切问题。
有解决这个问题的首选方法吗?显然,我可以添加类似
的内容if(this.ParentForm == null) { return; }
到ParentChanged事件或那些行。但这既不优雅也不安全。我是否忽略了一些事件或首选方式来实现这一目标?
答案 0 :(得分:0)
虽然检查null
引用并相应地转移代码(例如,不尝试引用丢失的对象)并不一定是坏的,但更好的方法是将UserControl
类与它们分离。父母。
也就是说,这些UserControl
类根本不应该了解其父表单类型。否则就是否定OOP的一个主要好处:代码重用。使用您当前的设计,即使您在不崩溃的情况下使用它,您也无法使用这些UserControl
对象,除非在此特定父表单类型的上下文中。
您今天可能认为,没关系,您永远不会想在任何其他环境中使用它们。但未来很难预测。例如,您可能决定要在父表单上使用仍应使用这些相同UserControl
对象的变体。
您应该做的是通过公共属性公开UserControl
状态,然后允许父表单根据需要初始化它们。
这是一个非常简单的例子(我省略了Designer创建的代码......我假设您可以从字段名称推断出我的意思):
partial class UserControl1 : UserControl
{
/* ... */
public bool IsMyFlagChecked
{
get { return checkBox1.Checked; }
set { checkBox1.Checked = value; }
}
/* ... */
}
partial class ParentForm : Form
{
/* ... */
private void SomeMethodThatAddsUserControl1()
{
UserControl1 uc1 = new UserControl1;
uc1.IsMyFlagChecked =
this.SomeParentFormPropertyUserControl1UsedToReferenceDirectly;
// other initialization for uc1...
Controls.Add(uc1);
}
/* ... */
}
(请注意,如果没有a good, minimal, complete code example说明您的问题,我无法提供比上述更详细的代码示例。如果这似乎无法解决您的问题,请编辑它,以便它提供了更多细节,包括更好的代码示例。)