在加载期间找到UserControl的ParentForm

时间:2016-06-09 06:37:01

标签: c# winforms

我正在尝试找到UserControl的ParentForm,因此我可以将一些事件处理程序挂钩。我尝试在UserControl上的ParentChanged事件处理程序中执行此操作,例如:

ParentChanged += delegate(object sender, EventArgs args)
{
  ParentForm.SomeEvent += ...
}

如果UserControl的Parent恰好是表单,这可以正常工作。但是,如果UserControl嵌入在容器控件中(在本例中为SplitContainer),则在将容器控件添加到顶级窗体的控件(在InitializeComponent方法中控制)之前,UserControl将添加到容器控件中。也就是说,InitializeComponent()从叶子向上构建层次结构,因此叶子不知道它们最终会在构造期间放置什么形式。

因此,当触发ParentChanged事件时,ParentForm在UserControl上为null,并且当UserControl的父代的父代更改时,我没有获得ParentChanged事件。我可以为父的ParentChanged事件添加监听器,但是我必须在整个控制层次结构上这样做,这不是特别优雅。

我基本上想知道ParentForm何时为UserControl更改。然而,没有这样的事件。我可以加入像Load事件这样的事情,但是this表示如果控件显示在MDI容器中,它每次都会被触发。那篇MSDN文章建议把东西放在构造函数中,但这就是我现在正在做的事情,并且由于事情初始化的时间而无法解决问题。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我在自己的customcontrol中也需要这个。 我将一个按钮子类化,在onclick中我需要知道表单。 因此,诀窍实际上并没有在加载中获取表单,而是在您需要时获取它。

这对我有用:

private Form GetParentForm(Control parent)
{
    Form Result = parent as Form;
    if (Result == null)
    {
        if (parent != null)
        {
            // Recursive is cool
            return GetParentForm(parent.Parent);
        }
    }
    return Result;
}

我像这样使用它

protected override void OnClick(EvnetArgs e)
{
    Form form = GetParentForm(Parent);
    if (form != null)
    {
        // do stuff here
    }
}