单击另一个用户控件上的按钮后动态加载用户控件 [英] Dynamically loading UserControl after clicking button on another UserControl
问题描述
我在表单上显示 UserControl 时遇到问题.
I have a problem with displaying UserControl on my Form.
简而言之程序:
- 在 Form1 中,我有一个按钮.单击此按钮后,在面板(容器)中动态加载了我的第一个 UserControl (new.cs).
- 在该面板上,我有另一个按钮,可通向另一个 UserControl (choice.cs),我想在 Form1 的同一个面板(容器)中显示它.
第一点效果很好,但第二点有问题.我想我必须纠正choice_button_Click 函数.有什么简单的方法吗?
The first point works good, but I have a problem with second one. I think I have to correct choice_button_Click function. Is there an easy way to do it?
这是我的代码:
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();
}
}
}
推荐答案
您的功能问题是您没有将 choice.Instance
放在 Form1
的实例中.相反,您正在创建一个新表单,将其放置在那里,然后丢弃该表单.
Your functional problem is that you aren't placing choice.Instance
inside your instance of your Form1
. You are creating a new form instead, placing it there, then discarding that form.
但是,您的设计也存在问题,您违反了原则,其中 UserControl
不应直接访问和修改其父表单.您最好向 @new
添加一个事件,从按钮单击引发该事件,然后在表单实例中处理该事件.
However, you also have an issue in your design, where you are violating the principal wherein a UserControl
shouldn't be directly accessing and modifying its parent form. You would be better off adding an event to @new
, raising that event from the button click, then handling that event in your form instance.
例如:
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:
And 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
实例并修改表单.
Now you're obviously going to be working on the same form instance, since it itself is the one handling the event. Also, @new
doesn't need to do any awkward lookup to find the proper Form1
instance and modify the form.
这篇关于单击另一个用户控件上的按钮后动态加载用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!