2009-12-24 95 views
1

我有一个窗体和一个UserControl。 UserControl有一个菜单,表单有一个tabtrip(General,Food,Vitamins等)。Winform和用户控件 - C#

在用户控件的,我有以下代码:(表格名称是frmForm,形式的标签名称是tabGeneral,tabFood,tabVitamins)

frmForm fm=new frmForm(); 
    fm.tabMain.Selected=tabVitamins; 

我打电话从用户控件这些线捕捉选项卡以在表单上进行选择,但不会选择维生素选项卡。

我哪里错了?我有访问说明符作为表单中的标签保护内部。

请指教。

感谢, Karthick

回答

7

当你写new frmForm(),你要创建的frmForm一个全新实例,然后将其丢弃。

若要获取控制您的控件的frmForm实例,请调用FindForm()方法并投射到frmForm

例如:

frmForm myForm = FindForm() as frmForm; 
if(myForm != null) 
    myForm.tabMain.SelectedTab = myForm.tabVitamins; 

如果控制一些其他的形式,该代码不会做任何事情。


顺便说一下,匈牙利语符号在.Net中被皱起了眉头。
您的表单可能应该被命名为MainForm

+0

谢谢SLaks。完美,我改变了myForm.tabMain.SelectedTab = frmForm.tabVitamins; 至 myForm.tabMain.SelectedTab = myForm.tabVitamins; – Karthick 2009-12-24 01:33:22

+0

是的,你是对的。我修正了这一点。 – SLaks 2009-12-24 01:40:04

+0

很好的答案,帮助了我。谢谢。 – MikeMalter 2011-05-20 23:49:14

1

你不应该创建新frmForm()的用户控件中。您可以将对frmForm的引用传递给用户控件。

在您的用户控件构造函数中尝试类似这样的操作。

private frmForm fm; 

public YourUserControl(frmForm fm) 
{ 
    this.fm = fm; 
} 

然后你可以使用。

fm.tabMain.Selected=tabVitamins; 

这有帮助吗?

+0

这会阻止设计人员使用该控件。 – SLaks 2009-12-24 01:19:18

+0

我刚刚在VS 2008中试过,看起来很好。你为什么认为它会阻止设计者使用控制器? – wes 2009-12-24 01:21:28

+0

设计人员要求控件具有公共无参数构造函数。 – SLaks 2009-12-24 01:22:04

3

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中使用的构造函数。

祝你好运!