从UserControl访问父表单



我在表单上有这些属性。

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

在设计时,用户可以更改LanguageID属性。我在我的表单上添加了一些自定义的Control对象。在那些对象构造器我想访问的形式的公共属性Languages,能够设置我的自定义控件的属性根据选择的LanguageID从形式的属性。

我已经尝试了这篇文章的解决方案,但是Site属性将只在设计时设置,而不是在运行时设置。运行时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;
}
}
}
}

如果这不是一个好的方法,请,我需要一些建议。

每个控制器都有一个父对象,您可以使用以下代码来获取表单:

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

或作为方法:

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

循环是必需的,因为您的控件可能在表单的另一个容器中。

最新更新