容器形式的控件来自子形式?

时间:2011-01-26 18:02:01

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

在容器形式中,我有菜单和按钮来打开表格。  enter image description here

这里我遇到一个问题,当我打开任何表格这些按钮和标签来到新打开的表格。 enter image description here

请指导我如何管理此问题?我想打开一个新表单并将这些容器表单的控件保留在它的背景中。

10 个答案:

答案 0 :(得分:5)

我也遇到了同样的问题。我得到了另一种解决方案,如下所述:

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

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

答案 1 :(得分:4)

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

请查看此Articlethis

尤其是:

  

父表单可能不包含任何控件。 >

编辑:添加了附加信息

答案 2 :(得分:4)

我想我明白你做了什么。您正在使用MDI并将菜单标签和按钮放在MDI父窗体上。您使用MDI客户端窗口执行了某些操作,通常是深灰色。也许你想出了如何更改其BackColor或更改Windows系统颜色。是的,你的屏幕拍摄了结果。问题是MDI客户端表单是MDI客户端窗口的父级。这使得他们在后面显示你在父表单上放置的控件。

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

答案 3 :(得分:1)

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

  • 使用单独的表单:有一个菜单表单,通常是大/最大化的,并通过将Parent属性设置为菜单表单来启动子表单,或者
  • 使用单个表单,但使用停靠库(我过去使用过DockPanel Suite)。这实际上是MDI表单的重新实现,具有额外的功能。这是一个可以运行的工作,但它可以让你构建一些不错的用户界面。

但是,这些都需要对您的UI代码进行重大更改。

答案 4 :(得分:1)

这里的主要技巧是将子表单视为控件。您将像任何其他控件一样创建子表单。当你使用这个方法时,你必须将它的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 :(得分:0)

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

如果它必须在那个主要形式和那些控件的兄弟中,那么你将不得不设置它的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);

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

非常简单

  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
    

答案 9 :(得分:0)

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

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