C#WinForms,在UserControl中添加UserControl

时间:2015-06-28 17:23:47

标签: c# winforms user-controls

我正在开发一个非常以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();

1 个答案:

答案 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);
    }

}