容器形式的控件优于子形式?

发布于 2024-10-14 13:40:30 字数 245 浏览 7 评论 0原文

在容器表单中,我有菜单和按钮来打开这些表单。 在此处输入图像描述

这里,当我打开任何表单时,这些按钮和标签来自新打开的表单,我遇到一个问题。 在此处输入图像描述

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

In a container form I have menu and buttons to open ther forms.
enter image description here

Here I am facing a problem when I open any form these buttns and lables come over newly opened form.
enter image description here

Please guide me how I can manage this issue? I want to open a new form and keep these container form's controls in back ground of it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

假装爱人 2024-10-21 13:40:30

我想我明白你做了什么。您正在使用 MDI,并将菜单标签和按钮放在 MDI 父窗体上。您对 MDI 客户端窗口做了一些操作,它通常是深灰色的。也许您已经知道如何更改其 BackColor 或更改 Windows 系统颜色。

是的,你的截图就是预期的结果。问题在于 MDI 客户端窗体是 MDI 客户端窗口的父级。这使得它们显示在您放置在父窗体上的控件后面

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

I think I see what you did. You are using MDI and you put the menu labels and buttons on the MDI parent form. You did something with the MDI client window, it is normally dark-gray. Maybe you figured out how to change its BackColor or changed the Windows system color.

Yes, your screenshot is then the expected result. The problem is that MDI client forms are parented to the MDI client window. Which makes them show up behind the controls you put on the parent form.

There is no workaround for this, you are going to have to change your UI. To keep MDI, put a Panel on the parent form and set its Dock property to Left. Move the menu controls on that. The MDI client window will now shrink, occupying the remainder of the parent form. And the child forms will constrain themselves to that area. The wee painful bit is that you'll have to reorganize the menu to fit the much smaller space available in the panel.

莫言歌 2024-10-21 13:40:30

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

  1. 插入计时器控件
  2. 我已将控件添加到面板容器中
  3. 并执行了以下操作

    private voidtimer1_Tick(对象发送者,EventArgs e)
    {
        if ((int)MdiChildren.GetLength(0) > 0)
        {
            panel1.Visible = false;
        }
        别的
        {
            panel1.Visible = true;
        }
    }
    

I've also got the same problem. I got an alternative solution as described below:

  1. Insert a timer control
  2. I've added the controls in a panel container
  3. And did the following

    private void timer1_Tick(object sender, EventArgs e)
    {
        if ((int)MdiChildren.GetLength(0) > 0)
        {
            panel1.Visible = false;
        }
        else
        {
            panel1.Visible = true;
        }
    }
    
节枝 2024-10-21 13:40:30

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

看看这篇文章这个

特别是这个:

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

编辑:添加附加信息

If it is a MDI application and you put controls in the parent window then they will be shown on top of any created child windows. You need to have your menu in a child window also, not on the parent form.

Look at this Article and this.

expecially this:

The parent Form may not contain any controls. >

Edit: Added Additional Information

奢华的一滴泪 2024-10-21 13:40:30

这里的主要技巧是将子窗体视为控件。您将像任何其他控件一样创建子窗体。当您使用此方法时,您必须将其 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.

更多详细信息此处

The main trick here is to treat child forms as Controls. You'll create a child form just like any other control. When you use this method, you have to set it's TopLevel to false - otherwise it won't work.

The following lines of code are used to create a child form:

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.

more details here

べ映画 2024-10-21 13:40:30

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

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

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

@Hans Passant has the correct answer, but you could also solve your issue by not using MDI forms at all. Some options:

  • Use separate forms: have a menu form, typically large/maximized, and launch child forms in front of it by setting their Parent property to the menu form, or
  • Use a single form, but with a docking library (I've used DockPanel Suite in the past). This is essentially a re-implementation of MDI forms, with extra features. This is a bit of work to get running, but it can let you build some nice UIs.

Both of these would require significant changes to your UI code, though.

温柔戏命师 2024-10-21 13:40:30

非常简单

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

  2. 将其加载到MDI表单加载

     MDI 表单加载编码..
    
     调暗 frm 为新 frm_chiled_mdi        
     frm.MdiParent = 我
     frm.Show()
    
  3. frm_chiled_mdi的表单加载编码

     Me.WindowState = FormWindowState.Maximized
     Me.BackgroundImageLayout = ImageLayout.Stretch
     Me.MaximizeBox = False
     Me.MinimizeBox = False
    
     尝试
         Me.BackgroundImage = Image.FromFile(Application.StartupPath + "\\logo.jpg")
     捕获 ex 作为异常
     结束尝试
    

Its Very Simple

  1. Create new form (frm_chiled_mdi) after mdi form, and decorate it as you wish (like button, picture, label etc.)

  2. Load it on MDI Form Load

     MDI Form Load Coding..
    
     Dim frm As New frm_chiled_mdi        
     frm.MdiParent = Me
     frm.Show()
    
  3. form load coding of 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
    
放手` 2024-10-21 13:40:30

该窗体似乎是其他子控件的同级控件。您必须将其作为该窗口的子窗口打开吗?难道它不能像一个非模式对话框而不是该主窗体的子窗口吗?

如果它必须位于主窗体中并且是这些控件的同级控件,那么您将必须设置它的 Z 顺序。没有相应的属性,因此您必须查看 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);

It appears as though that form is a sibling of those other child controls. Do you have to open it as a child of that window? Can't it be like a non-modal dialog box and not a child window of that main form?

If it has to be within that main form and a sibling of those controls, then you're going to have to set the Z-Order of it. There's no property for that, so you're going to have to look toward the Win32 API call, 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;

And call it something like this:

SetWindowPos((int)form.Handle,   // that form
             (int)insertAfter.Handle,  // some other control
             0, 0, 0, 0,
             SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
谁的新欢旧爱 2024-10-21 13:40:30

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

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

Call BringToFront() on each child form after showing them. Alternately, hook it to each child form's OnLoad method:

childForm.OnLoad += (s, e) => (s as Form).BringToFront();
痞味浪人 2024-10-21 13:40:30

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

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();
    }
}

I had this problem and solved it this way:

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();
    }
}
千秋岁 2024-10-21 13:40:30

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

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

I had the same issue and I have found the best solution for it. First of all you need to shift your controls in a panel. The add a "MdiChildActivate" event and write this,

private void Form1_MdiChildActivate(object sender, EventArgs e)
    {
        if (ActiveMdiChild != null)
            panel1.SendToBack();
        else
            panel1.BringToFront();
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文