我正在创建一个应用程序,其中我有一个主窗体,以及用户使用的几个不同的用户控件。这有助于我分割代码,管理程序的不同部分。以后可以很容易地扩展应用程序。
我正在尝试创建一个类,我在其中管理我想要在该类中调用一个函数的活动控件,并使用as参数作为应该变为活动状态的表单。
图像可以说明我如何尝试设置此应用程序。 请注意,控件管理器类不是下面显示的代码中的单独类,而是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;
}
}
总结我在寻找什么: 我有一个主窗体,显示不同的用户控件。我正在尝试创建一个单独的类,可以从我的项目中的每个控件/窗体访问。该类应该管理显示的控件。在上面的代码中,我说明了我是如何尝试这样做的,但这不会产生预期的结果。
答案 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顺序。
另一个问题是此功能直接在我们的主表单上。我不知道这将如何作为另一个部分类。它绝对值得一试。