【问题标题】:Show top most Child Form c#显示最顶部的子窗体 c#
【发布时间】:2016-04-20 16:59:50
【问题描述】:

如何在我的父表单中显示最上面的按钮单击子表单(带有停靠为填充的选项卡控件)? 它总是在父表单的 tabcontrol 后面显示表单,我什至使用过:

frm.TopMost = true;
frm.BringToFront();

仍然显示在后面。

【问题讨论】:

  • 当您说“子窗体”时,您的意思是 MDI 子窗体?
  • 是的先生,我正在尝试在我的父表单中显示选项卡控件的前面
  • 您将TopMost 用于MDI 孩子?两者不兼容。还有,2016年你还在用MDI吗?为什么?现在真的有点过时了,不熟悉了。也许一个简单的Owner 关系会更好?
  • @Jcl 是的,DevExpress' 绝对不是真正的 MDI - 您可以在 Spy++ 中轻松看到它。他们一直在伪造它,因为“真正的 MDI”已经很久没有更新了,今天真的很烂:)。 WPF 实际上非常棒,但它与 C# 的接口不如 Winforms,而且它改变了太多东西以使其对大多数 Winforms(和本机 Windows)开发人员具有吸引力。哦,好吧,我们必须在它真正受到关注之前消亡:)
  • @Luaan 这将是在啤酒面前进行的一次很棒的对话 :-) 我已经完成了我的 WPF 份额,已经发布了应用程序,我讨厌它的任何东西不需要“花哨”...喜欢绑定和 MVVM,但是 XAML(一种可以编写功能的声明性语言?)和可视化树实现,我讨厌它。这些天,我使用某种自烘焙的绑定(不是 winforms 数据绑定)混合了 Winform,并使用了自实现的 ICommand(一种 MVVM 和 MVP 的混合)。希望我能找到任何更适合我的 UI 系统,但我没有

标签: c# mdichild mdiparent


【解决方案1】:

你想要的都是不可能的。控件的 MDI 子项显示在名为 MdiClient 的控件(您不能直接选择)上,该控件不透明(也不能),默认情况下,始终位于父项中其他控件的后面表格。

因此,这样做的唯一方法是将MdiClient 覆盖父窗体中的控件:这将达到您的预期,但是当没有显示子窗体时它也会隐藏父控件(因为同样,MdiClient 不是,也不能是透明的)。

因此,唯一合理的方法是使用 TabControl 最大化子窗体,而不是直接在父窗体上使用 TabControl

或者您可以只在没有子窗口时显示您的TabControl。为此,请在父表单中创建一个计时器,并每隔一段时间检查一次:

if(MdiChildren.Length > 0)
   myTabControl.SendToBack();
else
   myTabControl.SendToFront();

这只有在 MDI 孩子总是最大化时才有效:当有任何孩子时,您的TabControl 将不可见(无论他们是否覆盖它)

更新

如 cmets 所述,您可以拥有“您自己的 MDI”,方法是在父窗体中拥有一个主机控件(例如 Panel)并在该控件中加载子窗体:

var form = new ChildForm();
form.TopLevel = false;
form.Parent = myHostPanel;
form.Show();

这将在面板中显示表单(您可以在其中找到并排序)...但是您将失去所有 MDI 管理,并且您必须跟踪您的孩子(并照顾如果需要,表格的事件)你自己。

使用这个解决方案,它非常笨拙,对于大型应用程序可能会变得混乱(除非你使用正确的系统)

作为总结

因为我们在 cmets 中讨论了这些方法

你可以用你自己的方式来做你想做的事,但是你会遇到各种各样的问题。

如果我是你,我会重新设计我的应用程序,这样就不需要你想要实现的目标。如果你不能这样做,唯一理智的方法就是在父窗体中没有这些控件,使用这些控件拥有一个始终最大化、不可关闭的 MDI 子窗体,并在每次需要工作时跳过该窗口MDI 子集合。

【讨论】:

  • 谢谢先生的回答。是否有其他方法可以使其他表单在任务栏或其他表单中不可见?
  • 您可以将属性ShowInTaskbar 设置为false,使您的窗口不显示在任务栏中。您还可以在“父”表单中将表单的父控件设为任何控件(只需设置Parent 属性,而不是MdiParent,并将表单TopLevel 属性设置为false
  • 可能使用定时器有性能问题,考虑使用MdiChildActivate之类的事件。
  • @mostafa8026 没错...使用具有合理间隔的计时器应该不是性能问题,但捕获 MdiChildActivate 可能会更好:您需要处理关闭或隐藏虽然也没有子表单,但没有 MdiChildDeactivate
  • @Luaan 完全正确......它也有关于 Win8+ 中窗口镶边的错误(I even filled one in connect -标记为无法修复,顺便说一句),因为表单被渲染为位图,并且由于某种原因,chrome 以 Win7 非航空风格呈现,即使在 Win8 或 10 上......你基本上必须制作自己的完整窗口系统:-)
【解决方案2】:

请说明您正在使用哪些框架的哪些组件以及您到目前为止所做的工作。如果没有这些信息,我建议使用以下解决方案(未经测试)。

在 ParentForm 的“ButtonClick”事件中执行以下操作:

ChildForm cf = new ChildForm();
cf.MdiParent = this;
cf.Show();

如果这不起作用,您可以添加一个

cf.Focus();

【讨论】:

  • 我已经做到了,先生..仍然无法正常工作,我正在使用.net framework 4。我的父表单充满了带有标签页的标签控件。我关心的是孩子表格显示在后面。,
【解决方案3】:

这个问题让我不舒服:)。经过大量测试,我真的找不到解决方案。 BringToFront() 功能和 SendToBack() 都不能正常工作。也许以下方法可以帮助您。我使用 Rectangle 类的 IntersectWith 函数并测试表单是否与 tabControl 相交。如果是这样,将选项卡控件可见性更改为 false,否则为 true。看看下面的代码:

首先在 mdi 父表单中公开表单声明:

public partial class MdiParentForm : Form
{
    Form frm = new Form();
}

之后,当您初始化子表单时,将一些处理程序添加到其 locationChanged 事件中,如下所示:

frm.MdiParent = this;
frm.LocationChanged += Frm_LocationChanged;
frm.Show();

最后,这是处理程序:

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,问题在于只要子窗体的任何点触及其矩形,选项卡控件就会隐藏和显示。移动子窗体会很可怕:-)

【讨论】:

  • 这样的问题是标签控件将隐藏和显示,只要子窗体的任何点 触摸它的矩形。移动子窗体会很可怕:-)
  • 我可以将标签页作为另一个表单的父表单(作为子表单)吗?
  • 标签页还是标签控件本身?
  • 如果可能,标签控件本身也不是标签页
  • 是的,有可能,看看this question
猜你喜欢
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多