简体   繁体   English

从用户控件访问父窗体

[英]Access Parent Form from a UserControl

I have these properties on a form.我在表单上有这些属性。

public enum LanguageID
{
    en, fr, de, it, ro
}

[Browsable(false)]
public Language[] Languages = new Language[]()
{
    new Language { LangID = LanguageID.en, TranslatedText = "One" },
    new Language { LangID = LanguageID.fr, TranslatedText = "Un"},
    new Language { LangID = LanguageID.de, TranslatedText = "Einer"}
    // and so on, for all other languages
}

public class Language
{
    public LanguageID LangID { get; set; } = LanguageID.en;
    public string TranslatedText { get; set; } = "One";
}

In design-time, user can change LanguageID property.在设计时,用户可以更改LanguageID属性。 I added some custom Control objects on my form.我在表单上添加了一些自定义Control对象。 In those objects constructors I want to access form's public property Languages , to be able to set a property of my custom controls according to selected LanguageID from form's property.在这些对象构造函数中,我想访问表单的公共属性Languages ,以便能够根据从表单的属性中选择的LanguageID来设置我的自定义控件的属性。

I've tried the solution from this post, but Site property will be set only in design-time, not in runtime.我已经尝试过这篇文章中的解决方案,但Site属性将仅在设计时设置,而不是在运行时设置。 In runtime Site property is null.在运行时Site属性为 null。

public ContainerControl ContainerControl
{
  get { return _containerControl; }
  set { _containerControl = value; }
}
private ContainerControl _containerControl = null;

// Custom object constructor
public MyControl()
{
    var langID = ((Form)ContainerControl).LanguageID; // the problem is here, ContainerControl is populated in DesignMode, but not in runtime. In runtime it's value is null
    var selectedLang = Array.Find(Form.Languages, l => l.LangID = langID);
    // code to set text here
}

public override ISite Site
{
  get { return base.Site; }
  set
  {
    base.Site = value;
    if (value == null)
    {
      return;
    }

    IDesignerHost host = value.GetService(
        typeof(IDesignerHost)) as IDesignerHost;
    if (host != null)
    {
        IComponent componentHost = host.RootComponent;
        if (componentHost is ContainerControl)
        {
            ContainerControl = componentHost as ContainerControl;
        }
    }
  }
}

If this is not the good approach, please, I need some advice.如果这不是好方法,请,我需要一些建议。

Each controller has a parent object and you can use the following code to get the form:每个控制器都有一个父对象,您可以使用以下代码来获取表单:

Type type = this.Parent.GetType();
Control x = this.Parent;
while (type.BaseType.Name != "Form")
{
    x = x.Parent;
    type = x.GetType();
}
// HERE x is your form

Or as a method:或者作为一种方法:

public Form GetParentForm()
{
    Type type = this.Parent.GetType();
    Control x = this.Parent;
    while (type.BaseType.Name != "Form")
    {
        x = x.Parent;
        type = x.GetType();
    }
    return (Form)x;
}

The loop is needed because your control might be inside another container inside of the form.需要循环是因为您的控件可能位于表单内的另一个容器内。

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

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