比MDI父母/子女表格更好的方法

已加入
2020年3月20日
留言内容
65
编程经验
10+
大家好

我是C#的新手,我90%的经验是旧语言。我正在忙于一个新的WinForms C#项目,该项目在主窗体上仅具有一个停靠的面板,并带有一排按钮来模仿菜单,当单击这些菜单按钮中的一个时,我只需要显示一个新窗体,但是我的左边菜单仍然可见且可单击。我正在将主窗体设置为mdi父窗体,并将要显示为子窗体的窗体设置为玩耍。这似乎可以正常工作,但是我有相当多的UI设计,并且子窗体显示得并不理想。所以我的问题确实是,在不使用mdi父子窗体的情况下,是否有更好的方法来实现这一目标?我也相信这种方法已经过时了。

非常感谢。
AJ
 

金西尼(Jmcilhinney)

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,563
地点
悉尼,澳大利亚
编程经验
10+
MDI仍然可以为正确的应用程序工作,但是许多应用程序已经为每个文档创建一个单独的窗口。就您而言,您实际上是在同时显示多个子窗口吗?如果不是,则不需要MDI,甚至不需要单独的表格。您可以对每个功能子集使用用户控件,然后根据需要创建,销毁,显示和隐藏它们。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
此外,还有Windows UI准则,请牢记:
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
MDI仍然可以为正确的应用程序工作,但是许多应用程序已经为每个文档创建一个单独的窗口。就您而言,您实际上是在同时显示多个子窗口吗?如果不是,则不需要MDI,甚至不需要单独的表格。您可以对每个功能子集使用用户控件,然后根据需要创建,销毁,显示和隐藏它们。

嗨Jm

多谢您的回覆,我一次只会显示一张表格,因此无须同时显示多个子表格。我必须做一些研究"您可以对每个功能子集使用用户控件,然后根据需要创建,销毁,显示和隐藏它们。"因为我从来没有做过这样的事情。每个表单将具有不同的控件和功能等。这些用户控件将是表单吗?
 

金西尼(Jmcilhinney)

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,563
地点
悉尼,澳大利亚
编程经验
10+
这些用户控件将是表格吗?
就像添加任何其他项(包括表单)一样,将用户控件添加到项目中。您打开“添加项目”对话框,然后选择用户控件项目模板。如果在解决方案资源管理器中右键单击项目,则会有一个专用菜单项。就像您添加的所有表单一样, 形式 类,因此所有用户控件都继承了 用户控件 班级。您可以使用与设计表单完全相同的方式来设计用户控件,然后以与使用任何其他控件完全相同的方式来使用它。生成时,它甚至会自动添加到工具箱中。请注意,理想情况下,您应将所有子控件设为私有,然后仅公开您特别需要的内容,例如您可以添加一个 细绳 属性以获取并设置 文本 一个孩子 文本框 。您还需要添加适当的事件,例如您可以在内部处理 点击 一个事件 按钮 然后养自己的 按钮点击 event.
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
就像添加任何其他项(包括表单)一样,将用户控件添加到项目中。您打开“添加项目”对话框,然后选择用户控件项目模板。如果在解决方案资源管理器中右键单击项目,则会有一个专用菜单项。就像您添加的所有表单一样, 形式 类,因此所有用户控件都继承了 用户控件 班级。您可以使用与设计表单完全相同的方式来设计用户控件,然后以与使用任何其他控件完全相同的方式来使用它。生成时,它甚至会自动添加到工具箱中。请注意,理想情况下,您应将所有子控件设为私有,然后仅公开您特别需要的内容,例如您可以添加一个 细绳 属性以获取并设置 文本 一个孩子 文本框 。您还需要添加适当的事件,例如您可以在内部处理 点击 一个事件 按钮 然后养自己的 按钮点击 event.

谢谢JM
我已经找到UserControl并将其添加到我的项目中,现在我对要研究的内容有了一个想法。我确定我会回发更多问题,因为这对我来说是全新的领域。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
实际上,这里有一些选择:
如最初建议的那样,您可以动态显示和隐藏窗口中已经存在的控件,或者动态添加和删除控件。通常,这就是许多现代基于Web的SPA(单页应用程序)的工作方式。

更简单的选择是对弹出的其他表单使用模式对话框,从用户那里收集信息,然后关闭该对话框。这可能像MDI应用程序风行之前的1980年代的倒退(主要是因为Apple Macintosh UI)。

另一个问题是用户是否必须以某种顺序的方式提供信息。如果是这样,那么1990年代的样式向导将可能是一个更好的UI,尤其是如果该程序的目标是仅生成一组结果并且没有真正的需要继续调整产生结果的参数的情况下。

我强烈建议您从问题中稍微退后一步,考虑一下程序的目的是什么,以及实现此目的的理想工作流程是什么。不要将自己束缚在菜单,工具栏,向导,对话框等的概念中。您可能最终发现,真正需要的只是一个自由的表单页面,用户可以在其中进行拖放"items"从调色板到表面并将东西连接在一起。或者,您可能会发现您在启动时仅向用户询问1或2个初始问题,并生成初始结果,那么用户只需要右键单击并从一小组预定义的操作中进行选择-右键单击可能更自然比点击工具栏按钮。
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
谢谢你们的所有投入,他们确实对我的研究以及如何最好地使该应用程序按我所需的方式工作提供了帮助。我总共有大约10个表单,这些表单需要来自用户的不同数据,所以要离开mdi父/子,我要做的就是在我的主表单上添加一个面板,并设置停靠属性以填充。显示我的新表单时,我使用下面的代码将它们添加到容器中,这看起来确实很好用,而不会像mdi那样在UI上发生奇怪的事情。

C#:
                    Form frm = new FrmSetupExchanges();
                    frm.TopLevel = false;
                    frm.ControlBox = false;
                    frm.Dock = DockStyle.Fill;
                    PnlContainer.Controls.Add(frm);
                    frm.Show();

你们预见到使用此方法会遇到任何问题吗?
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
Although it may seem to work now, stuffing a 形式 as a child window may lead to unexpected behavior in the future. It would be better to make FrmSetupExchanges into a 用户控件. This has the added benefit of not needing to call Show().

如果使用的是WinForms Designer,则设计用户控件与设计表单没有什么不同。只需将控件拖到设计区域并设置属性和事件即可。
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
感谢您对跳伞运动员的反馈,因此请澄清一下。
1.我需要为所有这10个用户提供一个新的用户控件"forms" ?
2.我可以使用与普通表单相同的方式来设计用户控件,唯一的区别是我需要为控件编码事件吗?
3.我是否在主表单面板中显示用户控件?还是将用户码头属性设置为填充?

非常感谢跳伞者的所有投入。
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
嗨,大家好

我一直在尝试使用控制,这是到目前为止的内容。
我已经从我的主窗体中删除了面板(我以前使用它来显示我的新窗体),我已经添加并设计了一个用户控件窗体,并使用以下代码对其进行调用。

C#:
                    UcDeposits uc = new UcDeposits();
                    Controls.Add(uc);
                    uc.Dock = DockStyle.Fill;
                    uc.BringToFront();

我现在似乎遇到的唯一问题是,当显示用户控件时,它首先填充了整个主窗体,然后重新调整大小以正确地适合,所以我在正确安装之前得到了这道可怕的画面。我是否应该仍在主窗体上使用停靠面板将用户控件窗体放入?还是在某个地方错过了一步?

非常感谢您的两次输入,本周我学到了很多东西。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
如果您正在这样做"Load" or "Shown" event, or any point after initially loading the form, yes, you will see a lot of the redrawing that happens. Ideally, you should do all that in the constructor before anything is displayed, but if you really must delay things until later because of dynamically adding and removing controls, use the SuspendLayout()ResumeLayout() methods to stop the redrawing until you are done adding/removing controls. It may also help to design your user controls to the ideal size that you will be using with your form.
 

约翰·H

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
1,076
地点
挪威
编程经验
10+
在添加控件以避免两次布局之前,设置Dock属性也可能有所帮助。
 

金西尼(Jmcilhinney)

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,563
地点
悉尼,澳大利亚
编程经验
10+
我建议像这样使用对象初始化程序:
C#:
var uc = new UcDeposits {Dock = DockStyle.Fill};
使用这样的对象初始化程序可确保构造后立即进行属性设置。您可以按照自己的喜好设置任意多个属性,并用逗号分隔。
 
Last edited:
已加入
2020年3月20日
留言内容
65
编程经验
10+
大家好

我已经尝试了一些方法,但是无法摆脱明显的调整大小问题,我进行了大量研究,并且似乎普遍认为可以在面板中显示用户控件。下面的代码运行良好,我现在只想弄清楚一旦打开用户控件窗体就如何关闭它。

C#:
                    UcDeposits uc = new UcDeposits();
                    PnlContainer.Controls.Add(uc);
                    uc.Dock = DockStyle.Fill;
                    uc.BringToFront();

再次感谢。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
像我们建议的那样,您的代码在哪里暂停和恢复布局?

在添加控件之前,您在哪里实现了设置停靠样式的建议?
 
已加入
2020年3月20日
留言内容
65
编程经验
10+
嗨跳伞

经过大量研究和对我的应用程序的更多计划后,我决定坚持将表单加载到停靠面板中的原始计划。我可以找到的关于此方法的唯一弊端是内存使用情况,幸运的是该应用程序非常小,使用WinForms可以为我提供所需的控件,因此我认为这不会成为太大的问题。但是再次感谢你们,由于您的建议和学习的努力,我走上了研究的重担。

问候
AJ。
 
最佳 底部