从用户控件更新主窗体中的标签

本文关键字:标签 窗体 用户 控件 更新 | 更新日期: 2023-09-27 18:29:45

在我当前的应用程序中,我有一个main form: frmMain,里面有一个statusstrip和一个label: lblStatus。我想从我的用户控件内部更新该标签,当我单击相关按钮时,我将其添加到我的主窗体中:

ucBeheer ucBeheer = new ucBeheer();
splitContainer1.Panel2.Controls.Add(ucBeheer);

当我执行操作时,我想从我的usercontrol内部更新lblStatus.我尝试将以下属性添加到我的主窗体中:

    public string updateStatus
    {
        get { return lblStatus.Text; }
        set { lblStatus.Text = value; }
    }

然后在我的用户控件中访问如下方法:

        frmMain mainForm = new frmMain();
        mainForm.updateStatus = "This is a test";

但这行不通,我知道这是因为我正在制作我frmMain的新对象,但我不知道如何解决这个问题?

我还找到了以下方法,带有Event Handler但我无法做到这一点,因为我的用户控件实际上还没有在我的 mainForm 中,直到我通过单击按钮将其添加到那里,所以我没有引用它。

所以我有点没有想法,我希望有人可以帮助我。谢谢托马斯

编辑:所以我设法通过以下方式做到这一点:

        frmMain owningForm = (frmMain)this.Parent.Parent.Parent.Parent;
        owningForm.updateStatus = "This is a test";

但是this.Parent.Parent.Parent.Parent...对我来说似乎不是很好的编码,有没有其他方法可以获得最顶级的父母?

从用户控件更新主窗体中的标签

您可以将这样的属性添加到您的用户控件中,有了这个属性,您可以访问用户控件所在的 frmMain。

public frmMain MainForm
{
    get
    {
        var parent = Parent;
        while (parent != null && (parent as frmMain) == null)
        {
            parent = parent.Parent;
        }
        return parent as frmMain;
    }
} 

更新:如果你只想要最顶层的父级,你可以使用这样的东西:

public Control TopMostParent
{
    get
    {
        var parent = Parent;
        while (parent.Parent != null)
        {
            parent = parent.Parent;
        }
        return parent;
    }
} 

甚至制作一个扩展方法:

public static Control TopMostParent(this Control control)
{
    var parent = control.Parent;
    while (parent.Parent != null)
    {
        parent = parent.Parent;
    }
    return parent;
} 

你的控制和形式必须沟通,所以一个需要"了解"另一个。实际上,这意味着对一个,另一个的引用。因此,您有 2 个选项:控件需要对窗体的引用,或者窗体需要对控件的引用。

我这样做的方法是让表单订阅控件发布的事件。这是仅对控件的一个方法的引用的形式。

class StatusChangedEventArgs : EventArgs
{
    public string Text { get; set; }
}
partial class MyControl : UserControl
{
    public event EventHandler<StatusChangedEventArgs> StatusChanged = delegate { };
    public void RaiseStatusChanged( string message )
    {
        StatusChanged( this, new StatusChangedEventArgs { Text = "message" } );
    }
}

然后,在您的表单中订阅事件:

...
ucBeheer ucBeheer = new ucBeheer();
ucBeheer.StatusChanged += HandleStatusChanged;
splitContainer1.Panel2.Controls.Add(ucBeheer);
...
partial class MyForm : Form
{
    void HandleStatusChanged( object sender, StatusChangedEventArgs args )
    {
        lblStatus.Text = args.Text;
    }
}
您可以使用按

名称引用Application.OpenForms FormCollection的主窗体:

frmMain owningForm = (frmMain)Application.OpenForms["frmMain"];
owningForm.updateStatus = "This is a test";