简体   繁体   English

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

[英]How to access Parent class function/control from a child user control loaded in a pannel

I have Main Form which contains a Panel which loads different Usercontrol into the panel. 我有Main Form,其中包含一个Panel,可以将不同的Usercontrol加载到面板中。 Now i need to access functions in the Main Form from the UserControl. 现在我需要从UserControl访问主窗体中的函数。 Below i have given my code; 下面我给了我的代码;

This is my main Windows form class: 这是我的主要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()
    {

    }
}

As you can see i am loading a usercontrol to the mainPannel. 如您所见,我正在将一个usercontrol加载到mainPannel。 Now lets look at the usercontrol: 现在让我们看一下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????

    }

}

I want to access mytest() function when button1 us clicked. 我想点击按钮1时访问mytest()函数。 I have tried alot of other solution but i am still confused. 我已经尝试了很多其他解决方案,但我仍然感到困惑。 I have used: 我用过:

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

This gives me reference to parent and i can change the form text but how can i access its functions??? 这给了我父母的参考,我可以改变表格文本但我怎么能访问它的功能???

Ok, the above answer will work but it is not good coding practice to pass in a "Parent Form" to a user control. 好的,上面的答案可行,但将“父表单”传递给用户控件并不是一个好的编码习惯。 UserControls should be located in a separate project from your forms project and your forms project should reference your control project in order to gain visiblity to them. UserControls应位于与表单项目不同的项目中,并且表单项目应引用您的控件项目以获得对它们的可见性。 Lets say for instance that you want this UserControl to be nested in another UserControl at some point. 让我们假设您希望此UserControl在某个时刻嵌套在另一个UserControl中。 Your code no longer works without overloading the constructor. 如果没有重载构造函数,您的代码将不再有效。 The better solution would be to use an event. 更好的解决方案是使用事件。 I have provided an implementation using a CustomEventArg. 我使用CustomEventArg提供了一个实现。 By doing this, your login UserControl can sit on anything and still work. 通过这样做,您的登录UserControl可以坐在任何东西上仍然可以工作。 If the functionality to change the parents text is not requried, simply do not register with the event. 如果不需要更改父文本的功能,则不要注册该事件。 Here is the code, hope this helps someone. 这是代码,希望这有助于某人。

Here is the form code: 这是表单代码:

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

Here is the "login" UserControl code (in my test solution, just a userControl with a button) 这是“登录”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));
        }
    }
}

And finally, the CustomEventArgs class: 最后,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;
    }
}

Writing your controls in this fashion, with no visibility to Forms will allow your UserControls to be completely reusable and not bound to any type or kind of parent. 以这种方式编写控件而不显示表单将允许您的UserControl完全可重用,而不是绑定到任何类型或类型的父级。 Simply define the behaviors a UserControl can trigger and register them when necessary. 只需定义UserControl可以触发的行为,并在必要时注册它们。 I know this is an old post but hopefully this will help someone write better UserControls. 我知道这是一个老帖子,但希望这会帮助别人写出更好的UserControls。

This may helps: 这可能有助于:

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
}

And

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

从您的UserControl:

((Form1)Parent).mytest();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM