C# 容器窗体中的控件是否超过子窗体?
在容器表单中,我有菜单和按钮来打开其他表单。 在这里,我面临一个问题,当我打开任何形式,这些烟头和标签来新打开的形式。C# 容器窗体中的控件是否超过子窗体?,c#,winforms,.net-3.5,mdi,mdichild,C#,Winforms,.net 3.5,Mdi,Mdichild,在容器表单中,我有菜单和按钮来打开其他表单。 在这里,我面临一个问题,当我打开任何形式,这些烟头和标签来新打开的形式。 请指导我如何处理此问题?我想打开一个新窗体,并将这些容器窗体的控件保留在它的后台。该窗体似乎是其他子控件的同级。你必须像孩子一样打开那扇窗户吗?它不能像一个非模态对话框,而不是主窗体的子窗口吗 如果它必须在主窗体和这些控件的同级中,那么您必须设置它的Z顺序。没有该属性,因此您必须查看Win32 API调用,SetWindowPos: [DllImport("user32.d
请指导我如何处理此问题?我想打开一个新窗体,并将这些容器窗体的控件保留在它的后台。该窗体似乎是其他子控件的同级。你必须像孩子一样打开那扇窗户吗?它不能像一个非模态对话框,而不是主窗体的子窗口吗 如果它必须在主窗体和这些控件的同级中,那么您必须设置它的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);
显示每个子窗体后,对其调用BringToFront()。或者,将其挂接到每个子窗体的OnLoad方法:
childForm.OnLoad += (s, e) => (s as Form).BringToFront();
如果它是一个MDI应用程序,并且您将控件放在父窗口中,那么它们将显示在任何创建的子窗口的顶部。您还需要在子窗口中设置菜单,而不是在父窗体上 看看这个,然后 特别是: 父窗体可能不包含任何控件。>
编辑:添加了附加信息我想我知道你做了什么。您正在使用MDI,并将菜单标签和按钮放在MDI父窗体上。您对MDI客户端窗口做了一些操作,它通常是深灰色的。也许你知道如何改变它的背景色或者改变Windows系统的颜色。是的,你的屏幕截图显示了结果。问题是MDI客户端窗体是MDI客户端窗口的父级。这使得它们显示在您放置在父窗体上的控件后面
没有解决方法,您必须更改您的UI。要保留MDI,请在父窗体上放置一个面板,并将其Dock属性设置为左侧。移动该菜单上的菜单控件。MDI客户端窗口现在将收缩,占据父窗体的其余部分。子窗体将自己约束到该区域。最痛苦的一点是,您必须重新组织菜单以适应面板中更小的可用空间。@Hans Passant给出了正确的答案,但您也可以通过根本不使用MDI表单来解决问题。一些选择:
- 使用单独的表单:拥有一个菜单表单,通常是大的/最大化的,并通过将其
父属性设置为菜单表单来启动前面的子表单,或者
- 使用单个表单,但使用停靠库(我以前使用过)。这本质上是MDI表单的重新实现,具有额外的功能。这需要做一些工作才能运行,但它可以让您构建一些漂亮的UI
不过,这两种情况都需要对UI代码进行重大更改。我也遇到了同样的问题。我得到了如下所述的替代解决方案:
private void timer1_Tick(object sender, EventArgs e)
{
if ((int)MdiChildren.GetLength(0) > 0)
{
panel1.Visible = false;
}
else
{
panel1.Visible = true;
}
}
这里的主要技巧是将子窗体视为控件。您将像创建任何其他控件一样创建子窗体。当您使用此方法时,必须将其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.
更多详细信息我遇到了这个问题,并通过以下方式解决了它:
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();
}
}
这很简单
MDI Form Load Coding..
Dim frm As New frm_chiled_mdi
frm.MdiParent = Me
frm.Show()
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
你的意思是说一个窗体上的按钮被绘制在另一个活动窗体的顶部。。。这很奇怪…是的,我有一个带菜单的容器表单。它有按钮,只显示控制面板一样的按钮和链接。打开表单时,btton保持在顶部,打开的表单位于容器表单和按钮之间。任何帮助plzPlz请查看我的编辑(附加图像)以了解说明。父窗体是MDI容器吗?请不要发布重复的问题。你已经在这里问过这个问题:标记问题不在菜单上。他们工作得很好。问题在于按钮和标签。是的,它是一个MDIapplication@haansi您的父窗体中是否有控件?Mark是否没有办法满足我的要求?看看这个Stackoverflow问题:+1这篇文章很好地描述了为什么您不应该在MDI应用程序中的父窗体上放置任何控件:是的,我担心可能没有。问题是您的父表单是MDI表单-我不认为有任何正确的方法,正如Hans所解释的。先生,请给出您提到的第1点的示例。