-2

编辑:我看到我在这篇文章上得到了很多反对意见。我试图解释我试图做什么,我的错误在哪里以及想往哪个方向发展。我要求深入了解我做错了什么。如果您投反对票;请告诉我为什么,这样我就可以改进这个问题。谢谢。

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

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

一张图片可以说明我如何尝试设置这个应用程序。插图请注意,控制管理器类不是我在下面显示的代码中的单独类,而是主窗体的部分类。非常欢迎任何关于如何在图像中获得它的提示:)

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

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

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

4

1 回答 1

2

好的,现在我了解所需的上下文。我们实际上在我的程序中做了一些非常相似的事情。这是我们如何做到这一点的基本概述......

布局

在主窗体上,我们有一个Panel容器,我们称之为pnlMain. 正是这个控件,我们从中添加和删除活动用户控件。我们在表示curActiveControl.

代码

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

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你可以简单地将它替换为新控件的备用实例。不过要小心引用和覆盖,这不是我个人以前尝试过的。

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

另一个问题是这个功能直接在我们的主窗体上。我不知道这作为另一个部分课程会有多好。不过,它绝对值得一试。

于 2012-10-29T14:09:36.293 回答