我正在使用C#winforms项目,我有一个用户控件,可以从工具条菜单中选择加载。我有一个字典查找设置在用户控件的表单加载时发生,用于其他功能。此外,当我关闭用户控件时,我只是使用“.Hide();”方法。我注意到当我第一次加载用户控件时一切都很好,但是当我关闭它并选择再次打开它时,它第二次创建了一个新的对象实例,从而抛弃了我的字典查找。因此,我写了一些代码来试图解决这个问题。
我需要做的是以某种方式说如果用户控件的实例已经存在,则不要创建该对象的新实例。相反,只需再次使用户控件可见。因此,我编写了代码以试图实现此目的。当我第一次选择项目时,一切都很好。当我隐藏用户控件并再次尝试重新打开时,没有任何反应。
以下是我为此目的编写的代码,它是在从工具条菜单中选择项目时发生的:
if (Controls.ContainsKey("CheckAvailUserControl"))
{
Controls["CheckAvailUserControl"].Dock = DockStyle.Fill;
Controls["CheckAvailUserControl"].Visible = true;
Controls["CheckAvailUserControl"].Show();
Controls["CheckAvailUserControl"].Refresh();
}
else
{
UserControl checkAvailUserControlLoad = new CheckAvailUserControl();
Controls.Add(checkAvailUserControlLoad);
checkAvailUserControlLoad.Dock = DockStyle.Fill;
checkAvailUserControlLoad.Visible = true;
checkAvailUserControlLoad.Show();
}
当我在调试器中跟踪我的代码时,它实际上是在上面的if / else语句的正确部分。它只是在我第二次尝试加载它时才在屏幕上显示用户控件。
问题是:关闭后如何让用户控件正确加载,然后再从工具条菜单中选择它?
答案 0 :(得分:9)
我认为Controls.ContainsKey(...)总是返回false,因为您在创建控件时从未为控件指定过名称。
如果在创建控件时,请说
//...
checkAvailUserControlLoad.Name = "Something"
//...
Controls.Add(checkAvailUserControlLoad);
然后
Controls.ContainsKey("Something")
将返回true,您将能够使用Controls["Something"]
答案 1 :(得分:2)
你走了:
private void button_Click(object sender, EventArgs e)
{
// pass in the containing panel
LoadControl<MyControls.MyControl>(panelContainer);
}
void LoadControl<T>(Panel panel) where T : Control, new()
{
T _Control = GetControl<T>(panel);
if (_Control == null)
{
_Control = new T();
_Control.Dock = DockStyle.Fill;
panel.Controls.Add(_Control);
}
_Control.BringToFront();
}
T GetControl<T>(Panel panel) where T : Control
{
Type _Type = typeof(T);
String _Name = _Type.ToString();
if (!panel.Controls.ContainsKey(_Name))
return null;
T _Control = panel.Controls[_Name] as T;
return _Control;
}
答案 2 :(得分:1)
这可能会有效,但我认为它有点倒退:你正在为可能通过移动旧代码解决的问题抛出新代码。
相反,请考虑事件在您的表单中的工作方式。我敢打赌,如果您将创建代码移动到稍微不同的事件,或者检测事件何时被触发并忽略它们,您可以以更好的方式解决问题。