2

我在一个 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 语句的正确部分。我第二次尝试加载它时,它只是没有在屏幕上显示用户控件。

问题是:如何在关闭用户控件后正确加载它,然后再次从工具条菜单中选择它?

4

3 回答 3

9

我认为 Controls.ContainsKey(...) 总是返回 false,因为您在创建控件时从未为控件分配名称。

如果,当你创建控件时,你说

//...
checkAvailUserControlLoad.Name = "Something"
//...
Controls.Add(checkAvailUserControlLoad);

然后

Controls.ContainsKey("Something") 

将返回 true,您将能够通过使用重新使用控件Controls["Something"]

于 2009-02-23T19:25:17.983 回答
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;
}
于 2010-02-03T22:12:30.480 回答
1

这可能可行,但我认为这有点倒退:您将新代码扔到一个可以通过移动旧代码来解决的问题上。

相反,请考虑事件在您的表单中是如何工作的。我敢打赌,如果您将创建代码移动到稍微不同的事件,或者检测到稍后触发事件的时间并忽略这些,您可以以更好的方式解决问题。

于 2009-02-23T19:38:36.453 回答