SLaks已经正确地指出了你的根本错误,并给出了一个有效的方法示例,通过调用方法FindForm来获取UserControl所在的窗体。
记住一个UserControl(和所有控件)也有一个'Parent属性,但是当然,UserControl可以放在窗体的另一个控件内(比如你的UserControl可能会有价值在窗体中的Panel上):在这种情况下,UserControl的Parent将是它在Form中的控件(比如Panel),而不是Form本身,但是'FindForm将做正确的事情来让你的Form上。
但是,每次使用FindForm时,您都会调用Method,并且“最佳实践”表明您想要执行的操作是在运行时将对该Form的引用“注入”到UserControl中,以便它可以总是轻松地访问它的Form属性,而不用调用'Method'。
在你的例子中,在实际的层面上,这个(调用方法)可能在性能上几乎没有什么区别,但是,当你到达一个使用WinForms和.NET的地方时,你可能会有一个用户控件需要频繁访问其父窗体,这将会得到回报,并且从长远来看,这是更好地构建代码的方式,以便进行维护。 Wes向您展示了一种您可以“嵌入”(注入)UserControl的托管窗体的方法:使用UserControl的重载构造函数。但是这需要您修改标准WinForms中的Designer.cs文件,我强烈建议您不要这样做,尽管它可以工作。特别是如果你在.NET中只是“脚踏实地”,我强烈建议你不要修改它,或者任何与Form的构造函数和它的内部调用有关的任何东西:InitializeComponent();另外,随着WinForms的进展,你将遇到许多你想要“对象”实例(一个控件,一个窗体,一个类的实例)的实例来包含对其他“对象。
如果你能理解并使用一个简单的使用“注射液”在这里,你将取得进展,使自己准备在未来处理更复杂的.NET编程。
另一种方法是在UserControl中放置一个公共属性,该属性可以在MainForm的代码中设置。在UserControl中有如下所示:
private frmForm ParentForm;
public frmForm UCParentForm
{
set { ParentForm = value; }
}
这样,就要在你的主窗体的代码,也许在这样的Load事件:
private void frmForm_Load(object sender, EventArgs e)
{
TheUserControl.UCParentForm = this;
}
或者当你需要,可以设置用户控件的“ParentForm属性一次。所以你已经使用方法FindForm()消除了。
在这种情况下,如果您只想访问UserControl的父表单上的某个特定控件(如TabControl),则可以考虑将该属性设置为TabControl类型,而不是Form:相同的编码如上所示技术可以在该用户控件中使用:
private TabControl mainFormTabControl;
public TabControl MainFormTabControl
{
set { mainFormTabControl = value; }
}
IMHO,它是当你在运行时动态地创建用户控件,使用重载的构造,如韦斯所暗示的,是最好的策略。并且使用重载的构造函数有许多其他许多.NET中使用的构造函数。
祝你好运!
谢谢SLaks。完美,我改变了myForm.tabMain.SelectedTab = frmForm.tabVitamins; 至 myForm.tabMain.SelectedTab = myForm.tabVitamins; – Karthick 2009-12-24 01:33:22
是的,你是对的。我修正了这一点。 – SLaks 2009-12-24 01:40:04
很好的答案,帮助了我。谢谢。 – MikeMalter 2011-05-20 23:49:14