Show top most Child Form c#
如何在我的父表单(带有一个停靠为填充的tabcontrol)中最上方显示单击按钮的子表单?
它总是在父窗体的tabcontrol的后面显示该窗体,我什至使用过:
1 2
| frm.TopMost = true;
frm.BringToFront(); |
仍然显示在后面。
-
当您说"儿童表格"时,您是指MDI儿童?
-
是的,先生,我试图在父表格中显示标签控件的前面
-
您为MDI孩子使用TopMost吗?两者不兼容。另外,您还在2016年使用MDI吗?为什么?如今,它确实已经过时了,还不熟悉。也许简单的Owner关系会更好?
-
@Luaan我不同意MDI已过时(无论如何,不??比Winforms更过时)。我正在做一个新的(基本上是重写的)LoB应用程序及其MDI(您可以取消固定的选项卡式MDI)...我尝试了许多方法,发现MDI是该特定应用程序和一个用户的最佳设计最喜欢
-
@Jcl可以,但是"带扩展坞的选项卡式MDI"很可能不使用Windows MDI基础结构,对吗?那就是过时的部分,而不是界面本身(尽管很多人不再理解它了)。我喜欢Visual Studios的" tabbed-pseudo-MDI"界面,但它不使用"真实" MDI,甚至不再使用"真实"窗口。
-
@Luaan Im不确定实现(我使用devexpress选项卡式MDI和对接控件,而不是重新发明轮子),但Id说它们在内部使用MDI。我也喜欢VSs接口,但是我在WPF中尝试的所有事情(无论是自己做的还是尝试第三方控件)都会很快变得混乱(免责声明:我讨厌开发WPF,讨厌我一直花在这样做上的所有时间,所以我的观点可能有偏见;-))。我希望有任何现代的,可以完全烘焙的桌面UI库,但是似乎没有(我想WPF是半熟的,不要让我开始使用UWP :-))
-
@Jcl是的,DevExpress绝对不是真正的MDI-您可以在Spy ++中轻松看到它。他们一直都在伪造它,因为"真正的MDI"还没有更新太久,以至于今天真的很烂:)。 WPF实际上非常出色,但是它不像Winforms那样与C#交互,并且它更改了太多东西,因此对于大多数Winforms(和本机Windows)开发人员来说都具有吸引力。哦,好吧,必须在它真正获得牵引力之前消灭它:)
-
@Luaan在啤酒面前,这将是一次很棒的对话:-)我已经完成了WPF的工作,发布了应用程序,并且我讨厌不需要"花哨的外观"的任何东西...爱绑定和MVVM,但是我讨厌XAML(一种可以在其中编写功能的声明性语言?)和可视化树实现。这些天,我使用某种类型的自烤绑定(不是winforms数据绑定)混合使用Winforms,并使用自实现的ICommands(混合了MVVM和MVP)。 Wished Id找到了任何更适合我的UI系统,但我没有
您想要的是不可能的。控件的MDI子级显示在名为MdiClient的控件(您不能直接选择)上,该控件不是透明的(并且不能是),默认情况下,它始终位于父级中其他控件的后面形成。
因此,执行此操作的唯一方法是在父窗体的控件上获取MdiClient:这将达到您期望的效果,但是当没有子窗体显示时,它也会隐藏父控件(再次, MdiClient不是,并且不能透明)。
因此,唯一合理的方法是使用TabControl最大化子窗体,而不是直接将TabControl放在父窗体上。
或者,您可以只在没有子窗口时显示TabControl。为此,请以父表形式创建一个计时器,并在每个间隔检查一次:
1 2 3 4
| if(MdiChildren.Length > 0)
myTabControl.SendToBack();
else
myTabControl.SendToFront(); |
这仅在MDI子项始终最大化的情况下才有效:当有任何子项(无论是否覆盖子项)时,您的TabControl将不可见
更新资料
如评论中所述,您可以通过在父窗体中具有宿主控件(例如Panel)并在该控件中加载子窗体来拥有"自己的MDI":
1 2 3 4
| var form = new ChildForm ();
form .TopLevel = false;
form .Parent = myHostPanel ;
form .Show(); |
这将在面板中显示表单(您可以在其中定位并按顺序排序)...尽管您失去了所有MDI管理,但您必须跟踪孩子(并照顾表单的事件)如果需要)自己。
我不会使用此解决方案,因为它很hacky,并且对于大型应用程序可能会变得混乱(除非您使用正确的系统)
作为总结
由于我们正在评论中讨论这些方法
您可以破解自己想做的方法,但是任何方法都会遇到各种各样的问题。
如果我是你,那么我将重新设计我的应用程序,以便不需要您想要实现的目标。如果您不能做到这一点,那么唯一的明智方法就是不将这些控件放在父窗体中,将一个始终最大化,不可关闭的MDI子窗体与这些控件一起使用,并在每次需要工作时跳过该窗口MDI儿童收藏。
-
谢谢您的回答。还有其他方法可以使其他窗体在任务栏或其他窗体中不可见吗?
-
将属性ShowInTaskbar设置为false,可以使窗口不在任务栏中显示。您还可以使表单的父级成为"父"表单内的任何控件(只需设置Parent属性而不是MdiParent,并将表单TopLevel属性设置为false)
-
也许使用计时器会导致性能问题,请考虑使用类似MdiChildActivate的事件。
-
@ mostafa8026没错...使用具有合理间隔的计时器应该不是性能问题,但是捕获MdiChildActivate可能会更好:尽管您也需要处理子窗体的关闭或隐藏,但没有MdiChildDeactivate
-
@Jcl,可以通过为主窗体创建一个事件来完成。更改mdiChildren.Count()时可以调用此事件。
-
MdiChildren集合是不可观察的,因此无论如何,您都需要通过轮询来跟踪它……您可以在许多事件中进行跟踪,但是最简单的方法就是拥有一个计时器。一个100/200毫秒的计时器对于Winforms应该足够好(无论如何,复杂的Winforms应用程序中的大多数重绘总会花费很多时间),并且完全不应该是性能问题。
-
请注意,非TopLevel窗口的行为与窗体完全不同。例如,您不会获得激活(WM_ACTIVATE仅发送到顶级窗口)-您需要编写自己的窗口。它基本上变成了可以拖动的Panel,几乎没有其他内容。性能也可能会受到影响,因为它们没有在DWM上渲染到自己的表面上,因此您不会得到硬件加速的运动(即,在拖动孩子时需要重画父母)。实际上,它不是很棘手-那就是Windows的工作方式。 .NET仅有一个称为" Form"的"特殊"窗口,该窗口通常是顶级的。
-
@Jcl或者您可以确保通过您自己的方法添加所有MDI子级:)
-
@Luaan那完全正确...它也有关于Win8 +中的窗口镶边的错误(我什至在连接中填充了一个-标记为不会修复,顺便说一句),因为该表单被渲染为位图,并且出于某种原因,镶边被渲染在Win7非航空风格中,甚至在Win8或10上...您基本上必须制作自己的完整窗口系统:-)
-
哦,是的,但是添加了-和-或删除了(或隐藏了),您需要订阅它们的关闭事件,调整大小事件等。如果我要执行类似的操作,则最好使用计时器(然后,Id永远不要设计一个像这样的应用程序,但是那是不可能的;-))
-
@Jcl可以工作,谢谢,我想做的正是这件事。
这个问题让我不舒服:)。经过大量测试,我真的找不到解决方案。 BringToFront()功能和SendToBack()均无法正常工作。也许以下方法可以为您提供帮助。我使用Rectangle类的IntersectWith函数并测试表单是否与tabControl相交。如果是这样,将选项卡控件的可见性更改为false,否则为true。看一下下面的代码:
首先在MDI父表单上公开表单声明:
1 2 3 4
| public partial class MdiParentForm : Form
{
Form frm = new Form ();
} |
之后,初始化子窗体时,向其locationChanged事件添加一些处理程序,如下所示:
1 2 3
| frm.MdiParent = this;
frm.LocationChanged += Frm_LocationChanged;
frm.Show(); |
最后,这是处理程序:
1 2 3 4 5 6 7 8 9 10 11 12 13
| private void Frm_LocationChanged (object sender, EventArgs e )
{
Rectangle tabControlRectangle = new Rectangle (tabControl1 .Location, tabControl1 .Size);
Rectangle childFormRectangle = new Rectangle (frm .Location, frm .Size);
if (tabControlRectangle .IntersectsWith(childFormRectangle ))
{
tabControl1 .Visible = false;
}
else
{
tabControl1 .Visible = true;
}
} |
多亏@Jcl,问题在于,只要子窗体的任何点接触其矩形,选项卡控件都将隐藏并显示。移动子窗体将是可怕的:-)
-
问题在于,只要子窗体的任何点接触其矩形,选项卡控件都将隐藏并显示。移动子窗体将是可怕的:-)
-
我可以将标签页设为其他表单(作为子表单)的父级吗?
-
标签页还是标签控件本身?
-
选项卡控件本身或选项卡页(如果可能)
-
是的,有可能,看看这个问题
请说明您正在使用哪些框架的组成部分以及到目前为止已完成的工作。没有这些信息,我建议以下解决方案(未经测试)。
在ParentForm的" ButtonClick"事件中,执行以下操作:
1 2 3
| ChildForm cf = new ChildForm ();
cf .MdiParent = this;
cf .Show(); |
如果这样不起作用,您可以添加一个
-
香港专业教育学院已经做到了,先生..仍然无法正常工作,即时通讯使用.net framework4。我的父表单充满了带有标签页的标签控件。我担心的是后面显示的子表单。