Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Winform一个窗体下不同页面的多个UserControl_C#_Winforms_User Controls - Fatal编程技术网

C# Winform一个窗体下不同页面的多个UserControl

C# Winform一个窗体下不同页面的多个UserControl,c#,winforms,user-controls,C#,Winforms,User Controls,我正在尝试使用Winform构建一个应用程序UI,其中包含多个页面。假设软件将在启动时请求登录凭据,然后登录到仪表板。然后用户可以选择进入不同的页面,如:Page1-Page2-Page3 现在我计划制作一个表单,所有这些页面都是单独的用户控件。因此,根据要求,我将更改这些用户控件的可见性 现在,为了做到这一点,我把下面的代码放在Form1.cs中 ControlLogin ucLogin = new ControlLogin(); ucLogin.Location = new Syst

我正在尝试使用Winform构建一个应用程序UI,其中包含多个页面。假设软件将在启动时请求登录凭据,然后登录到仪表板。然后用户可以选择进入不同的页面,如:Page1-Page2-Page3

现在我计划制作一个表单,所有这些页面都是单独的用户控件。因此,根据要求,我将更改这些用户控件的可见性

现在,为了做到这一点,我把下面的代码放在Form1.cs中

  ControlLogin ucLogin = new ControlLogin();
  ucLogin.Location = new System.Drawing.Point(12, 67);
  this.Controls.Add(ucLogin);

这个很好用。但是,当从ControlLogin.cs打开任何用户控件时,我如何将新的用户控件(比如Page1Control)添加到表单1的列表中?

您需要为页面开发一些事务逻辑。我建议在主窗体上使用面板作为容器。在此容器中,您将放置当前用户控件,即用户选择的控件

例如:

internal void ReplaceUserPage(Control container, UserControl userRequest)
{
    if (container.Controls.Count == 1)
    {
        container.Controls.RemoveAt(0);
    }
    container.Controls.Add(userRequest);
    userRequest.Dock = DockStyle.Fill;
}
如果您没有动态页面,那么可以将它们全部设置为单例。这样,每个实例都将按需创建,并保存在内存中,随时可以重用。因此,当用户单击菜单或按钮打开页面时,您可以

UserControl requested = Page1Control.GetInstance();
ReplaceUserPage(container, requested);

使用singleton,您甚至不需要保存控件列表。我并不是说这是最好的或完美的,也不是一种适合所有人的方式。有许多控制事务方法。这取决于系统的复杂性和其他因素。

我觉得您选择的基本布局不错

您实际的问题似乎是:如何从这些UCs引用表单

这与以下问题密切相关:如何从其他形式引用一种形式或其部分?这里经常有人问这个问题

以下是我建议您应该做的:

  • 创建一个公共函数,用于打开每个UCs
    openLogin
    openPageOne
  • 更改每个UC的构造函数,使其包含一个
    Form1
    作为参数(假设您的表单具有默认名称),并相应地如下调用它:
    ControlLogin ucLogin=new ControlLogin(this)
  • 在UCs构造函数中,您希望将传入的表单存储在类变量中
  • 以您所写的形式:

    public void openLogin(Form1 f)
    {
      ControlLogin ucLogin = new ControlLogin(this);
      ucLogin.Location = new System.Drawing.Point(12, 67);
      this.Controls.Add(ucLogin);
    }
    
    
    public void openPageOne(Form1 f)
    {
      ..
    }
    
    在加州大学:

    现在您可以引用表单中的所有公共字段和方法,可能如下所示

    if (logingIsOK) mainForm.openPageOne();
    

    RAD方法是使用。您只需要在用户控件中有一个对表单的引用。以一种简单、通用的方式,您已经按照
    按钮\u loadStuff\u Click(..){Form myParent=this.Parent;NextPage NextPage=new NextPage();myParent.Controls.Add(NextPage);}
    进行了操作。要获得更完善的引用,您需要将其声明为real from类型,默认情况下称为
    Form1
    。有了这个,你也可以访问表单中的所有(公共)字段。我理解你的单例概念,我最初的计划也是这样做的。今晚让我更深入地讨论这个项目。稍后我们会回来发表评论。谢谢分享,谢谢分享。这就是我要找的。除此之外,你能再给我介绍一些吗。。也就是说,我计划实现一些分组机制,如下所示。。每个组可以有多个页面(UCs)。一个组进入视图后,所有其他组都应不可见。这样我就可以实现PageOne,PageTwo下的内部页面。我是否可以将这些控件添加到多个阵列(组)的列表中,并在其中循环以更改可见性?是和是。把它们列在一个列表中可能是个好主意。然后,在显示新函数之前,可以在openXXX函数中隐藏所有内容。然而,你需要做出决定:你想让它们到处都是吗?如果没问题,你就得把它们处理掉。这实际上取决于它们包含的内容。也许DB连接是免费的还是保持开放的?你决定!一个人甚至可能想事先创造所有的东西,但这又取决于:这会不会让事情一开始变得太慢,还是会让事情变得更快另外:是否要在页面之间来回移动。。?。。。。。但是一个
    List myPages
    当然是个好主意,也是一个
    ucBaseClass currentPage
    变量。页面之间的循环将在那里。。但每次打开一个页面时,它都会显示它的初始阶段,即所有字段都是空白值。展示我认为展示/隐藏对我来说很好。是的,如果出现一些数据库连接问题,我将不得不考虑处理。好的,但请记住,显示/隐藏不会重置任何字段。因此,要么删除uc,并在必要时处理uc,要么编写重置函数,以便重置soem并保留其他值。。还要注意“Dispose”和“remove”之间的区别。您只需要处理那些可识别的东西!流就是一个例子,大多数GDI+的东西,比如位图就是另一个例子。。还要注意,处理本身不会递归地工作!您需要自己检查所有嵌套的IDisPobles。。因此,对于列表,您需要将它们全部列举出来。。
    if (logingIsOK) mainForm.openPageOne();