单击另一个UserControl上的按钮后动态加载UserControl

时间:2018-07-02 20:19:29

标签: c# winforms

我在窗体上显示UserControl时遇到问题。

程序简而言之:

  1. 在Form1中,我有一个按钮。单击此按钮后,将在面板(容器)中动态加载我的第一个UserControl(new.cs)。
  2. 在该面板上,我还有另一个按钮可引至另一个UserControl(choice.cs),我想将其显示在Form1上的同一面板(容器)中。

第一点很好,但第二点我有问题。我认为我必须更正choice_button_Click函数。有简单的方法吗?

这是我的代码:

Form1.cs:

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void new_button_Click(object sender, EventArgs e)
        {
            if (!container.Controls.Contains(@new.Instance))
            {
                container.Controls.Add(@new.Instance);
                @new.Instance.Dock = DockStyle.Fill;
                @new.Instance.BringToFront();
            }
            else
            {
                @new.Instance.BringToFront();
            }
        }

        public Panel getContainer()
        {
            return container;
        }
    }
}

new.cs:

namespace WindowsFormsApp1
{
    public partial class @new : UserControl
    {
        private static @new _instance;
        public static @new Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new @new();
                return _instance;
            }
        }

        public @new()
        {
            InitializeComponent();
        }

        private void choice_button_Click(object sender, EventArgs e)
        {
            using (Form1 main = new Form1())
            {
                if (!main.getContainer().Controls.Contains(choice.Instance))
                {
                    main.getContainer().Controls.Add(choice.Instance);
                    choice.Instance.Dock = DockStyle.Fill;
                    choice.Instance.BringToFront();
                }
                else
                {
                    choice.Instance.BringToFront();
                }
            }    
        }
    }
}

choice.cs:

namespace WindowsFormsApp1
{
    public partial class choice : UserControl
    {
        private static choice _instance;
        public static choice Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new choice();
                return _instance;
            }
        }

        public choice()
        {
            InitializeComponent();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您的功能性问题是您没有将choice.Instance放在您的Form1实例中。您正在创建一个新表单,将其放置在此处,然后丢弃该表单。

但是,您的设计中还存在一个问题,即您违反了UserControl不应直接访问和修改其父表单的主体。您最好将事件添加到@new,通过单击按钮引发该事件,然后在表单实例中处理该事件。

例如:

new.cs:

namespace WindowsFormsApp1
{
    public partial class @new : UserControl
    {
        private static @new _instance;
        public static @new Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new @new();
                return _instance;
            }
        }

        public event EventHandler StepCompleted;

        public @new()
        {
            InitializeComponent();
        }

        private void choice_button_Click(object sender, EventArgs e)
        {
            StepCompleted?.Invoke(this, EventArgs.Empty);
        }
    }
}

和Form1.cs:

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void new_button_Click(object sender, EventArgs e)
        {
            if (!container.Controls.Contains(@new.Instance))
            {
                container.Controls.Add(@new.Instance);
                @new.Instance.Dock = DockStyle.Fill;
                @new.Instance.BringToFront();
            }
            else
            {
                @new.Instance.BringToFront();
            }
        }

        private void new_StepCompleted(object sender, EventArgs e)
        {
            if (!container.Controls.Contains(choice.Instance))
            {
                container.Controls.Add(choice.Instance);
                choice.Instance.Dock = DockStyle.Fill;
                choice.Instance.BringToFront();
            }
            else
            {
                choice.Instance.BringToFront();
            }
        }
    }
}

现在您显然将在同一个表单实例上工作,因为它本身就是处理事件的那个实例。另外,@new无需进行任何笨拙的查找即可找到正确的Form1实例并修改表单。