在c#中从A类更新B类中的GUI组件

时间:2012-10-29 13:58:31

标签: c# .net class

编辑:我看到我在这篇文章中得到了很多关注。我试图解释我尝试做什么,我的错误和方向想要去哪里。我要求洞察我做错了什么。如果你downvote;请求告诉我为什么,所以我可以改进这个问题。感谢。

我正在创建一个应用程序,其中我有一个主窗体,以及用户使用的几个不同的用户控件。这有助于我分割代码,管理程序的不同部分。以后可以很容易地扩展应用程序。

我正在尝试创建一个类,我在其中管理我想要在该类中调用一个函数的活动控件,并使用as参数作为应该变为活动状态的表单。

图像可以说明我如何尝试设置此应用程序。 Illustration请注意,控件管理器类不是下面显示的代码中的单独类,而是mainform的部分类。关于如何在图像中获得它的任何提示都非常受欢迎:)

管理所有活动表单的类如下所示:请注意,所有用户控件都只是一个用户控件,上面有一些按钮/文本框等。根本没有添加任何代码。

    public partial class STP2Main 
        {
// I make each UserControl accessable for the whole class
            SetupDeviceControl.SetupDevice SetupDev = new SetupDeviceControl.SetupDevice();
            GenConfigFileControl.GenConfigFileControl GenConfFile = new GenConfigFileControl.GenConfigFileControl();
            Monitoring.MonitoringControl Monitor = new Monitoring.MonitoringControl();
            GenEncKeyControl.GenEncKeyControl GenEncKey = new GenEncKeyControl.GenEncKeyControl();
            MenuControl.MenuControl MenuControl = new MenuControl.MenuControl();        

            public void SelectActiveWindow()
            {
                // Any active control should be hidden thats what this function does:
                HideCurrentActiveControl();
                // Check whether the window is already created
                if (!WindowExists())
                { // if not created; create the windows: 
                    switch (STP_Design.ProgramParameters.C.NextActiveControl)
                    {
                        case STP_Data.Data.SetupDeviceControl: // control 1:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.SetupDeviceControl;
                            STP_Design.ProgramParameters.C.SetupDeviceControlIsCreated = true;
                            SetupDev.Parent = this;
                            SetupDev.Location = new Point(3, 30);
                            SetupDev.Show();
                            SetupDev.BringToFront();
                            break;
                        case STP_Data.Data.MonitoringControl: //control 2:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.MonitoringControl;
                            STP_Design.ProgramParameters.C.MonitoringControlIsCreated = true;
                            Monitor.Parent = this;
                            Monitor.Location = new Point(3, 125);
                            Monitor.Show();
                            Monitor.BringToFront();
                            break;
                        case STP_Data.Data.MenuControl: // control 3
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.MenuControl;
                            STP_Design.ProgramParameters.C.MenuControlIsCreated = true;  
                            MenuControl.Location = new Point(3, 30);
                            MenuControl.Parent = this;
                            MenuControl.Show();
                            MenuControl.BringToFront();
                            break;
                    }
                }
                else
                { // window is already created so needs to be called to front again:
                    switch (STP_Design.ProgramParameters.C.NextActiveControl)
                    {
                        case STP_Data.Data.SetupDeviceControl:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.SetupDeviceControl;
                            SetupDev.BringToFront();
                            break;
                        case STP_Data.Data.MonitoringControl:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.MonitoringControl;
                            Monitor.Visible = true;
                            Monitor.BringToFront();
                            break;
                        case STP_Data.Data.AdvancedMenu:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.AdvancedMenu;
                            tabControl1.Visible = true;
                            tabControl1.BringToFront();
                            break;

                        case STP_Data.Data.MenuControl:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.MenuControl;
                            MenuControl.Visible = true;
                            MenuControl.BringToFront();
                            break;
                    }

                }
                btnMenu.BringToFront();

            }
    // some functions which are called above are not shown; not relevant for this question
    }

我的体验如下:我完全没有错误。但控制根本不会改变。如果我调用一个窗口,它只创建一次,因为我确实把它作为我的Mainform的部分类。 (我已经尝试了一个完整的单独类,这确实导致了线程错误,因为我不是一个经验丰富的c#程序员,我试图避免使用部分类。)

我会添加另一个功能;什么都不做:

    private void HideCurrentActiveControl()
    {
        switch (STP_Design.ProgramParameters.C.CurrentActiveControl)
        {
            case STP_Data.Data.SetupDeviceControl:
                SetupDev.Visible = false;
                break;
            case STP_Data.Data.MonitoringControl:
                tabControl1.Visible = false;
                Monitor.Visible = false;
                break;
            case STP_Data.Data.GenConfFileControl:
                GenConfFile.Visible = false;
                break;
            case STP_Data.Data.GenEncKeyControl:
                GenEncKey.Visible = false;
                break;
            case STP_Data.Data.MenuControl:
                MenuControl.Visible = false;
                break;
            case STP_Data.Data.AdvancedMenu:
                tabControl1.Visible = false;
                break;
            default:
                tabControl1.Visible = false;
                break;

        }
    }

我已经尝试调试这部分代码并执行语句,但我看不到任何更改。

我想我已经展示了我想要做的事情;以及我如何尝试这样做。我的问题是:我如何访问这些表单,以便我可以从一个单独的类(或者在这种情况下是主表单的部分类)中管理它们。

然后我有了这个最后一个功能,它做了一些奇怪的事情。在我调用SelectActiveWindow()函数之前,我将变量STP_Design.ProgramParameters.C.NextActiveControl更新为例如:... AdvancedMenu。 (这是在那之前... MenuControl)但它总是表明它仍然是MenuControl。我的代码中没有任何地方可以在我启动函数之前更改该值。 (我也尝试将nextcontrol作为函数SelectActiveWindow()的参数,但这样做也是如此)

    private bool WindowExists()
    {
        switch (STP_Design.ProgramParameters.C.NextActiveControl)
        {
            case STP_Data.Data.SetupDeviceControl:
                if (STP_Design.ProgramParameters.C.SetupDeviceControlIsCreated)
                    return true;
                else
                    return false;
            case STP_Data.Data.MonitoringControl:
                if (STP_Design.ProgramParameters.C.MonitoringControlIsCreated)
                    return true;
                else
                return false;
            case STP_Data.Data.GenConfFileControl:
                if (STP_Design.ProgramParameters.C.GenConfFileIsCreated)
                    return true;
                else
                    return false;
            case STP_Data.Data.GenEncKeyControl:
                if (STP_Design.ProgramParameters.C.GenEncKeyControlIsCreated)
                    return true;
                else
                    return false;
            case STP_Data.Data.AdvancedMenu:
                return true;
            case STP_Data.Data.MenuControl:
                if (STP_Design.ProgramParameters.C.MenuControlIsCreated)
                    return true;
                else
                    return false;

            default:
                return false;
        }
    }

总结我在寻找什么: 我有一个主窗体,显示不同的用户控件。我正在尝试创建一个单独的类,可以从我的项目中的每个控件/窗体访问。该类应该管理显示的控件。在上面的代码中,我说明了我是如何尝试这样做的,但这不会产生预期的结果。

1 个答案:

答案 0 :(得分:2)

好的,现在我了解所需的背景。我们实际上在我的程序中做了类似的事情。以下是我们如何做的基本概要......

<强>布局

在主窗体上,我们有一个 Panel 容器,我们称之为pnlMain。我们添加和删除活动用户控件就是这个控件。我们在表示curActiveControl的表单上的全局级别还有一个 UserControl 对象。

<强>代码

当用户通过其中一个菜单选择一个窗口时,我们运行一个看起来像这样的函数

switch (UserSelection)
{
    case "Page 1":
        if(curActiveControl.GetType() != typeOf(Page1Control))
        {
            pnlMain.Controls.Remove(curActiveControl);
            curActiveControl = new Page1Control();
            //do setup and configuration things
            pnlMain.Controls.Add(curActiveControl);
        }
        //do some post processing things
        break;
    //other pages/specific page controls
}

Refresh();

这种特定方法的缺点是页面本身不是持久性的,所以如果有条目或变量要在会话中而不是仅在页面上有效,则必须将它们存储在其他全局中对象并从用户控件的Load或Constructor方法重新加载它们。

您可以执行相同的操作,但不是每次为curActiveControl创建新的控件实例,您只需将其替换为新控件的备用实例即可。但要注意参考和覆盖,这不是我个人以前尝试过的。

我们使用的方法中的关键是保存用户控件的Panel。我们只是更改主面板中显示的控件,而不是在任何给定的时间点都不存在其他控件,而不是调整大量用户控件的可见性和Z顺序。

另一个问题是此功能直接在我们的主表单上。我不知道这将如何作为另一个部分类。它绝对值得一试。