【问题标题】:Controls in container form come over child form?容器形式的控件超越子形式?
【发布时间】:2011-01-26 18:02:01
【问题描述】:

在容器表单中,我有菜单和按钮来打开表单。

当我打开任何表单时,这些按钮和标签出现在新打开的表单上时,我遇到了一个问题。

请指导我如何解决这个问题?我想打开一个新表单并将这些容器表单的控件保留在它的后台。

【问题讨论】:

  • 你的意思是说一个表单上的按钮被绘制在另一个活动表单的顶部......这很奇怪......
  • 是的 Shekhar,我有一个带有菜单的容器表单。它有按钮,只显示控制面板,如按钮和链接。打开表单时,按钮保持在顶部,打开的表单位于容器表单和按钮之间。任何帮助请
  • 请查看我的编辑(附加图片)以获取说明。
  • 父窗体是MDI容器吗?
  • 请不要发布重复的问题。你已经在这里问过这个问题:stackoverflow.com/questions/4808109/…

标签: c# winforms .net-3.5 mdi mdichild


【解决方案1】:

我也遇到了同样的问题。我得到了如下所述的替代解决方案:

  1. 插入计时器控件
  2. 我在面板容器中添加了控件
  3. 然后做了以下事情

    private void timer1_Tick(object sender, EventArgs e)
    {
        if ((int)MdiChildren.GetLength(0) > 0)
        {
            panel1.Visible = false;
        }
        else
        {
            panel1.Visible = true;
        }
    }
    

【讨论】:

    【解决方案2】:

    我想我明白你做了什么。您正在使用 MDI,并将菜单标签和按钮放在 MDI 父窗体上。您对 MDI 客户端窗口做了一些处理,它通常是深灰色的。也许你想出了如何改变它的 BackColor 或者改变了 Windows 系统的颜色。是的,你的屏幕截图了它的结果。问题是 MDI 客户端窗体是 MDI 客户端窗口的父级。这使得它们显示在您放在父窗体上的控件之后。

    没有解决方法,您将不得不更改您的 UI。要保留 MDI,请在父窗体上放置一个 Panel 并将其 Dock 属性设置为 Left。移动菜单控件。 MDI 客户端窗口现在将缩小,占据父窗体的其余部分。子窗体会将自己限制在该区域。有点痛苦的是,您必须重新组织菜单以适应面板中更小的可用空间。

    【讨论】:

      【解决方案3】:

      如果它是一个 MDI 应用程序并且您将控件放在父窗口中,那么它们将显示在任何创建的子窗口的顶部。您还需要将菜单放在子窗口中,而不是在父窗体中。

      看看这个Articlethis

      特别是这个:

      父窗体可能不包含任何控件。 >

      编辑:添加附加信息

      【讨论】:

      • 标记问题与菜单无关。他们工作正常。问题在于按钮和标签。是的,它是一个 MDI 应用程序
      • @haansi 你的父表单中有控件吗?
      • 马克有没有办法做我想做的事?
      • 看看这个 Stackoverflow 问题:stackoverflow.com/questions/4129760/…
      • +1 这篇文章很好地说明了为什么不应该在 MDI 应用程序的父窗体上放置任何控件:bytes.com/topic/visual-basic-net/answers/…
      【解决方案4】:

      这里的主要技巧是将子窗体视为控件。您将像创建任何其他控件一样创建子窗体。使用此方法时,必须将其 TopLevel 设置为 false - 否则将不起作用。

      以下代码行用于创建子表单:

      Form childForm = new Form(); //initialize a child form
      
      childForm.TopLevel = false; //set it's TopLevel to false
      
      Controls.Add(childForm); //and add it to the parent Form
      childForm.Show(); //finally display it
      
      childForm.BringToFront(); //use this it there are Controls over your form.
      

      更多详情here

      【讨论】:

        【解决方案5】:

        @Hans Passant 有正确的答案,但您也可以完全不使用 MDI 表单来解决您的问题。一些选项:

        • 使用单独的表单:有一个菜单表单,通常是大/最大化的,并通过将其Parent 属性设置为菜单表单来在其前面启动子表单,或者
        • 使用单个表单,但带有一个对接库(我过去使用过DockPanel Suite)。这本质上是对 MDI 表单的重新实现,具有额外的功能。这需要一些工作才能开始运行,但它可以让您构建一些漂亮的 UI。

        不过,这两者都需要对您的 UI 代码进行重大更改。

        【讨论】:

        • 先生,请举例说明您提到的第 1 点。
        【解决方案6】:

        看起来好像该表单是那些其他子控件的兄弟。你必须作为那个窗口的孩子打开它吗?它不能像一个非模态对话框而不是那个主窗体的子窗口吗?

        如果它必须在该主窗体中并且是这些控件的兄弟,那么您将不得不设置它的 Z-Order。没有属性,所以你将不得不查看 Win32 API 调用,SetWindowPos

        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        public static extern bool SetWindowPos(
        int hWnd, // window handle
        int hWndInsertAfter, // placement-order handle
        int X, // horizontal position
        int Y, // vertical position
        int cx, // width
        int cy, // height
        uint uFlags); // window positioning flags
        
        
        const uint SWP_NOSIZE = 0x1;
        const uint SWP_NOMOVE = 0x2;
        const uint SWP_SHOWWINDOW = 0x40;
        const uint SWP_NOACTIVATE = 0x10;
        

        然后这样称呼它:

        SetWindowPos((int)form.Handle,   // that form
                     (int)insertAfter.Handle,  // some other control
                     0, 0, 0, 0,
                     SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
        

        【讨论】:

          【解决方案7】:

          在显示每个子窗体后调用 BringToFront()。或者,将其连接到每个子窗体的 OnLoad 方法:

          childForm.OnLoad += (s, e) => (s as Form).BringToFront();
          

          【讨论】:

          • 是的,我担心它可能不会。问题是您的父表单是 MDI 表单 - 正如 Hans 所解释的那样,我认为没有任何方法可以正确地做到这一点。
          【解决方案8】:

          我遇到了这个问题并以这种方式解决了它:

          using System;
          using System.Collections.Generic;
          using System.ComponentModel;
          using System.Data;
          using System.Drawing;
          using System.Linq;
          using System.Runtime.InteropServices;
          using System.Text;
          using System.Windows.Forms;
          
          namespace WindowsFormsApplication1
          {
              public partial class Form1 : Form
              {
              [DllImport("user32.dll", SetLastError = true)]
              static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
          
              Form2 F2;
              public Form1()
              {
                  InitializeComponent();
                  F2 = new Form2();
              }
          
              private void Form1_Load(object sender, EventArgs e)
              {
                  Panel P1 = new Panel();
                  P1.Location = new Point(0, 0);
                  P1.Height = this.Height;
                  P1.Width = this.Width;
                  P1.BackColor = Color.Transparent;
                  this.Controls.Add(P1);
          
                  SetParent(F2.Handle, P1.Handle);
                  F2.Owner = this;
          
                  F2.Show();
              }
          }
          

          【讨论】:

            【解决方案9】:

            很简单

            1. 在mdi表单之后创建新表单(frm_chiled_mdi),并根据需要进行装饰(如按钮、图片、标签等)

            2. 在 MDI 表单加载中加载它

               MDI Form Load Coding..
              
               Dim frm As New frm_chiled_mdi        
               frm.MdiParent = Me
               frm.Show()
              
            3. frm_chiled_mdi 的表单加载编码

               Me.WindowState = FormWindowState.Maximized
               Me.BackgroundImageLayout = ImageLayout.Stretch
               Me.MaximizeBox = False
               Me.MinimizeBox = False
              
               Try
                   Me.BackgroundImage = Image.FromFile(Application.StartupPath + "\\logo.jpg")
               Catch ex As Exception
               End Try
              

            【讨论】:

              【解决方案10】:

              我遇到了同样的问题,我找到了最好的解决方案。首先,您需要在面板中移动控件。添加一个“MdiChildActivate”事件并写这个,

              private void Form1_MdiChildActivate(object sender, EventArgs e)
                  {
                      if (ActiveMdiChild != null)
                          panel1.SendToBack();
                      else
                          panel1.BringToFront();
                  }
              

              【讨论】:

                猜你喜欢
                • 2018-04-09
                • 1970-01-01
                • 2018-03-01
                • 2010-12-16
                • 1970-01-01
                • 2013-04-02
                • 1970-01-01
                • 2012-10-10
                • 1970-01-01
                相关资源
                最近更新 更多