Sur*_*rja 4 c# user-controls parent-child winforms
我有Main Form,其中包含一个Panel,可以将不同的Usercontrol加载到面板中.现在我需要从UserControl访问主窗体中的函数.下面我给了我的代码;
这是我的主要Windows窗体类:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
loadlogin();
}
private void loadlogin()
{
login log = new login();
mainPannel.Controls.Clear();
mainPannel.Controls.Add(log);
}
public void mytest()
{
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我正在将一个usercontrol加载到mainPannel.现在让我们看一下usercontrol:
public partial class login : UserControl
{
string MyConString = "";
public login()
{
InitializeComponent();
}
public void button1_Click_1(object sender, EventArgs e)
{
//I want to call the parent function mytest(); HOW????
}
}
Run Code Online (Sandbox Code Playgroud)
我想点击按钮1时访问mytest()函数.我已经尝试了很多其他解决方案,但我仍然感到困惑.我用过:
Form my = this.FindForm();
my.Text = "asdasfasf";
Run Code Online (Sandbox Code Playgroud)
这给了我父母的参考,我可以改变表格文本但我怎么能访问其功能???
好的,上面的答案可行,但将"父表单"传递给用户控件并不是一个好的编码实践.UserControls应位于与表单项目不同的项目中,并且表单项目应引用您的控件项目以获得对它们的可见性.让我们假设您希望此UserControl在某个时刻嵌套在另一个UserControl中.如果没有重载构造函数,您的代码将不再有效.更好的解决方案是使用事件.我使用CustomEventArg提供了一个实现.通过这样做,您的登录UserControl可以坐在任何东西上仍然可以工作.如果不需要更改父文本的功能,则不要注册该事件.这是代码,希望这有助于某人.
这是表单代码:
public Form1()
{
InitializeComponent();
loadlogin();
}
private void loadlogin()
{
login log = new login();
//Registers the UserControl event
log.changeParentTextWithCustomEvent += new EventHandler<TextChangedEventArgs>(log_changeParentTextWithCustomEvent);
mainPannel.Controls.Clear();
mainPannel.Controls.Add(log);
}
private void log_changeParentTextWithCustomEvent(object sender, TextChangedEventArgs e)
{
this.Text = e.Text;
}
Run Code Online (Sandbox Code Playgroud)
这是"登录"UserControl代码(在我的测试解决方案中,只是带有按钮的userControl)
public partial class login : UserControl
{
//Declare Event with CustomArgs
public event EventHandler<TextChangedEventArgs> changeParentTextWithCustomEvent;
private String customEventText = "Custom Events FTW!!!";
public login()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//Check to see if the event is registered...
//If not then do not fire event
if (changeParentTextWithCustomEvent != null)
{
changeParentTextWithCustomEvent(sender, new TextChangedEventArgs(customEventText));
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,CustomEventArgs类:
public class TextChangedEventArgs : EventArgs
{
private String text;
//Did not implement a "Set" so that the only way to give it the Text value is in the constructor
public String Text
{
get { return text; }
}
public TextChangedEventArgs(String theText)
: base()
{
text = theText;
}
}
Run Code Online (Sandbox Code Playgroud)
以这种方式编写控件而不显示表单将允许您的UserControl完全可重用,而不是绑定到任何类型或类型的父级.只需定义UserControl可以触发的行为,并在必要时注册它们.我知道这是一个老帖子,但希望这会帮助别人写出更好的UserControls.
这可能有助于:
public partial class Form1 : Form
{
//Other codes
private void loadlogin()
{
login log = new login(this); //CHANGE HERE
mainPannel.Controls.Clear();
mainPannel.Controls.Add(log);
}
//Other codes
}
Run Code Online (Sandbox Code Playgroud)
和
public partial class login : UserControl
{
Form1 _parent; //ADD THIS
public login(Form1 parent)
{
InitializeComponent();
this._parent = parent; //ADD THIS
}
public void button1_Click_1(object sender, EventArgs e)
{
this._parent.mytest(); //CALL WHAT YOU WANT
}
}
Run Code Online (Sandbox Code Playgroud)