我正在开发一个非常以GUI为中心的项目,使用自定义UserControl拖放对象。我在表单上创建和显示UserControl时没有问题。我遇到问题的地方是创建一个不同类型的UserControl并将其与第一个相关联。
我有一个名为HardwareComponent的类,它是主窗体的子类。当对象构造时,我想要一个名为ComponentPanel的对象也可以构造,但也可以作为控件添加到主窗体中。这样,在使用单个调用创建新Component时,Panel会自动创建,但它们仍然是表单上的两个独立控件对象。
这是一个snippit:
class HardwareComponent : UserControl
{
public ComponentPanel panel;
public HardwareComponent()
{
panel = new ComponentPanel();
panel.Location = new Point(this.Right + 5, this.Top);
panel.Name = Guid.NewGuid().ToString();
Parent.Controls.Add(panel);
}
}
从字面上看,ComponentPanel对象:
class ComponentPanel : UserControl
{
public string guid { get; set; }
public ComponentPanel()
{
}
}
*未显示的是OnPaint覆盖方法
如果我将ComponentPanel的创建移动到表单类,它显示没有问题,但现在我必须从表单类创建两个对象。我觉得让Component创建Panel更简洁。
无论如何,当我执行上面的代码时,它会在尝试添加' panel'时抛出NullReferenceException。到表单(硬件组件类的父级)。我试图让面板对象成为一个公共全局变量,认为它是一个"权限"问题。仍然没有骰子。
基本上我希望这个UserControl创建另一个UserControl,但将其添加到表单中。这是最佳做法吗?或者我是否必须从表单类中添加两者?
编辑: 汉斯在这里回答了更深层的问题我没有意识到null引用异常实际指向" Parent"。我觉得它不喜欢我的对象。我没有想到这样的事实,因为我在运行时动态创建对象,然后定义它的属性,然后将其添加到表单,Parent没有定义。所以构造函数不知道父母是谁。
我这样做的主要目的是从逻辑角度出发。这两个对象可以被认为是同一个。该组件在表单上显示为块。双击它时,会出现一个面板,显示该块内的内容。两个对象必须同时可见并且可以彼此自由移动,因此它不仅仅是视图改变的原因。
我的解决方案是创建一个方法来创建在创建Component对象后从主窗体调用的bastard子对象。例如:
this.Controls.Add(dummyComponent);
dummyComponent.InitializePanel();
答案 0 :(得分:0)
我同意这样做是一个糟糕的设计。然而,实现此目的的一种方法是重写OnParentChanged()并创建"兄弟"控制那里:
class HardwareComponent : UserControl
{
public ComponentPanel panel = null;
public HardwareComponent()
{
}
protected override void OnParentChanged(EventArgs e)
{
if (this.panel == null && this.Parent != null)
{
this.panel = new ComponentPanel();
this.panel.Location = new Point(this.Right + 5, this.Top);
this.panel.Name = Guid.NewGuid().ToString();
this.Parent.Controls.Add(panel);
}
base.OnParentChanged(e);
}
}