Winform&用户控制 - C#

时间:2009-12-24 01:08:17

标签: c# .net winforms user-controls

我有一个Form和一个UserControl。 UserControl有一个菜单,表格有一个标签(一般,食物,维生素等)。

在UserControl中,我有以下代码:(表单名称为frmForm,表单中的选项卡名称为tabGeneral,tabFood,tabVitamins)

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

我从UserControl调用这些行来捕获选项卡以在表单上选中,但它不会选择维生素选项卡。

我哪里错了?对于表单中的选项卡,我有访问说明符作为Protected Internal。

请建议。

谢谢, Karthick

3 个答案:

答案 0 :(得分:7)

当您编写new frmForm()时,您正在创建一个全新的 frmForm实例,然后将其丢弃。

要获取包含您控件的frmForm实例,请调用FindForm()方法并转换为frmForm

例如:

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

如果控件是其他形式,则此代码不会执行任何操作。


顺便说一句,匈牙利的符号在.Net中不受欢迎 您的表单应该命名为MainForm

答案 1 :(得分:3)

SLaks正确地指出了你的基本错误,并通过调用方法'FindForm来获得一个有效的方法示例,以获取位于UserControl的表单。

记住UserControl(和所有控件)也有'父属性',但是,当然,UserControl可以放在窗体上的另一个控件中(比如你的UserControl可能是在Form上的Panel中):在这种情况下,UserControl的Parent将是它在Form上的控件(比如Panel),而不是Form本身,但'FindForm会做正确的事情来获取它所在的Form

但是每次使用'FindForm时都会调用一个方法,而“最佳实践”表明你想要做的是在运行时将一个对Form的引用“注入”UserControl,这样它就可以无需调用“方法”即可轻松访问其Form属性。

在你的例子中,在实际的层面上,这个(调用Method)可能在性能上几乎没有差别,但是,当你到达一个WinForms和.NET的地方你可能有一个UserControl 需要非常频繁地访问其父表单,这将获得回报,而且从长远来看,这是构建代码以进行维护的更好方法。

Wes向您展示了一种可以“嵌入”(注入)UserControl的托管表单的方法:使用UserControl的重载构造函数。但是这需要你修改标准WinForms中的Designer.cs文件,我强烈建议你不要这样做,即使它会起作用。特别是如果您只是在.NET中“站稳脚跟”,我强烈建议您不要修改它,或者与Form的构造函数及其内部调用有关的任何内容:InitializeComponent();

此外,随着WinForms的发展,您将遇到许多情况,您希望“对象”实例(Control,Form,Class的实例)包含对“对象”的其他实例的引用

如果你能理解并在这里使用一个简单的“注入”,那么你将在未来做好准备,为将来处理更复杂的.Net编程做好准备。

另一种方法是在UserControl中放置一个Public Property,可以在MainForm的代码中设置。在UserControl中,例如:

private frmForm ParentForm;

public frmForm UCParentForm
{
    set { ParentForm = value; }
}

然后在你的主窗体的代码中,也许在这样的Load事件中:

private void frmForm_Load(object sender, EventArgs e)
{
    TheUserControl.UCParentForm = this;
}

或者在需要时,将UserControl的'ParentForm属性设置一次。所以你已经消除了使用方法'FindForm()。

在这种情况下,如果你只想访问UserControl的父窗体上的特定控件,比如TabControl,你可能会认为你想要设置你设置的属性TabControl,而不是Form:相同的编码技术如上所示可以在UserControl中使用:

private TabControl mainFormTabControl;

public TabControl MainFormTabControl
{
    set { mainFormTabControl = value; }
}
imho,当你在运行时动态创建UserControl时,使用重载的构造函数,正如Wes所说,是最好的策略。使用重载的构造函数有很多很多其他用于.NET的东西。

祝你好运!

答案 2 :(得分:1)

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

在你的用户控件构造函数中尝试这样的事情。

private frmForm fm;

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

然后你可以使用。

fm.tabMain.Selected=tabVitamins;

这有帮助吗?