如何从面板中加载的子用户控件访问父类函数/控件

本文关键字:控件 用户 访问 父类 类函数 加载 | 更新日期: 2023-09-27 18:06:34

我有一个主表单,它包含一个面板,它加载不同的用户控件到面板。现在我需要从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()
    {
    }
}

你可以看到我正在加载一个用户控件到mainpanel。现在让我们看看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????
    }
}

我想访问mytest()函数时,button1我们点击。我已经尝试了很多其他的解决方案,但我仍然感到困惑。我用过:

 Form my = this.FindForm();
 my.Text = "asdasfasf";

这给了我参考父母,我可以改变形式文本,但我怎么能访问它的功能??

如何从面板中加载的子用户控件访问父类函数/控件

好的,上面的答案将工作,但它不是一个很好的编码实践,在"父窗体"传递给用户控件。用户控件应该位于与窗体项目分开的项目中,窗体项目应该引用控件项目以获得对它们的可见性。比如说,你想要这个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;
}

下面是"login"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));
        }
    }
}

最后,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;
    }
}

以这种方式编写控件,对窗体不可见,将允许您的UserControls完全可重用,并且不绑定到任何类型或类型的父控件。只需定义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
}

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
    }
}

From your UserControl:

((Form1)Parent).mytest();