简体   繁体   English

C#中动态创建的用户控件

[英]Dynamically Created User Controls In C#

I am working in a C# winforms project and I have a user control which gets loaded upon its selection from a tool-strip menu. 我在C#winforms项目中工作,我有一个用户控件,从工具条菜单中选择加载它。 I have a dictionary lookup set to occur upon form load of the user control for other functionality. 我有一个字典查找设置在用户控件的表单加载时发生,用于其他功能。 Also, when I close the user control I am just using the ".Hide();" 此外,当我关闭用户控件时,我只是使用“.Hide();” method. 方法。 I noticed that when I load the user control the first time everything is fine, but when I close it and choose to open it again the 2nd time it creates a new instance of the object thus throwing off my dictionary lookup. 我注意到当我第一次加载用户控件时一切都很好,但是当我关闭它并选择再次打开它时,它第二次创建了一个新的对象实例,从而抛弃了我的字典查找。 Therefore, I wrote some code in an attempt to fix the issue. 因此,我写了一些代码来试图解决这个问题。

What I need to do is to somehow say that if an instance of the user control already exists, do not create a new instance of that object. 我需要做的是以某种方式说如果用户控件的实例已经存在,则不要创建该对象的新实例。 Instead, just make the user control visible again. 相反,只需再次使用户控件可见。 Therefore I have written code in an attempt to accomplish this purpose. 因此,我编写了代码以试图实现此目的。 When I select the item the first time, everything is fine. 当我第一次选择项目时,一切都很好。 When I hide the user control and try to re-open it again nothing happens. 当我隐藏用户控件并尝试再次重新打开它时,没有任何反应。

The following is the code I have written for this purpose which occurs upon the selection of the item from the tool-strip menu: 以下是我为此目的编写的代码,它是在从工具条菜单中选择项目时发生的:

      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();
       }

When I trace through my code in the debugger it is in fact hitting the right parts of the above if/else statement. 当我在调试器中跟踪我的代码时,它实际上是在上面的if / else语句的正确部分。 Its just not displaying the user control on the screen the 2nd time I attempt to load it. 它只是在我第二次尝试加载它时才在屏幕上显示用户控件。

The question is: How do I get the user control to load correctly after I close it, then select it from the tool-strip menu again? 问题是:关闭后如何让用户控件正确加载,然后再从工具条菜单中选择它?

I think that Controls.ContainsKey(...) is always returning false, because you never assigned a name to your control when you created it. 我认为Controls.ContainsKey(...)始终返回false,因为您在创建控件时从未为控件指定过名称。

If, when you create the control, you say 如果,当你创建控件时,你说

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

then 然后

Controls.ContainsKey("Something") 

will return true, and you'll be able to re-use the control by using Controls["Something"] 将返回true,您将能够通过使用Controls["Something"]重新使用该控件

Here you go: 干得好:

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;
}

This could work, but I think it's a little bit backwards: you're throwing new code at a problem that could be solved instead by moving your old code. 这可能会起作用,但我认为它有点倒退:你正在抛出一个可以通过移动旧代码来解决问题的新代码。

Instead, think about how the events work in your form. 相反,请考虑事件如何在您的表单中工作。 I bet that if you move your creating code to a slightly different event, or detect when the event is fired later and ignore those, you could fix the problem in a much nicer way. 我敢打赌,如果您将创建代码移动到稍微不同的事件,或者检测事件何时被触发并忽略它们,您可以以更好的方式解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM