1首先,新建WinForm的.NetFramWork的工程并添加2个Form:

2设置 Form1为MDI主窗口;

【属性】——

将以上属性改为 True;

另外,也可以采用代码形式:

this.IsMdiContainer = true;//设置容器属性

来实现同样的功能,此Demo采用代码来实现;

3设置Form2为Form1的子窗口;

在Form1的Load事件中添加如下代码:

private void Form1_Load(object sender, EventArgs e)
{
frm2.MdiParent = this;
frm2.StartPosition = FormStartPosition.CenterScreen;//设置子窗体在父窗体中间显示
frm2.Show();
}

至此,即可实现MDI多窗口编程;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

接下来,运用之前学习的委托与事件来实现一些功能;

【1】在弹出的Form2的上面自动生成2个控件,一个Textbox,一个Button;在Form2实现的关键代码如下:

public Form2()
{
InitializeComponent();
button1.Top = 50;
button1.Text = "Say Hello";
this.Controls.Add(button1);
this.Controls.Add(textbox1);

【2】点击Button“Say Hello”会让Button的标题显示到Textbox上;此功能输入事件模型中的——自己的成员事件被自己的成员事件处理器来订阅这种;关键代码如下:

>>事件订阅:

public Form2()
{ button1.Click += this.Action1;

>>另外一部分——事件处理器 方法:

private void Action1(object sender, EventArgs e)
{
this.textbox1.Text = this.button1.Text;

【3】点击Button“Say Hello”会让Form1窗口的标题栏事件发生更新;

由于Form1和Form2不在同一个Class;实现此功能仍然第一个想到是事件,但是,事件处理器(方法)里无法直接操作Form的属性;于是自然地想到了委托;

第一步:创建委托:注意——委托实际是一种特殊的类,所以委托的创建(定义)一定记得一般在NameSpace下,与Class同一级别;代码如下:

namespace ParentFormDemo
{
public delegate void ActionDelegate(object sender, EventArgs e);//【1】定义委托
public partial class Form1 : Form
{

第二步:在Form2中定义委托变量(因为事件实在Form2中发生的,必须顶一个委托变量作为Form2的Public字段成员,然后再在Form1中访问,即可实现绑定Form1中的方法):

public partial class Form2 : Form
{
public ActionDelegate actionDelegate1 = null;//【2】定义委托变量

在Form1中绑定定义满足签名的方法;

private void Form1_Load(object sender, EventArgs e)
{
frm2.actionDelegate1 = ChangeTitle;//【3】绑定委托
frm2.MdiParent = this;
frm2.StartPosition = FormStartPosition.CenterScreen;//设置子窗体在父窗体中间显示
frm2.Show();
}

满足签名的方法:

public  void ChangeTitle(object sender, EventArgs e)
{
this.Text = DateTime.Now.ToString("HH:mm:ss .fff") + ">>子窗口的按钮被按下";
}

再同上一个功能是实现,事件绑定该方法,此处由于都是同一个Button click事件的响应,故只需在同一个事件处理器(方法)中添加对委托的调用即可;

 private void Action1(object sender, EventArgs e)
{
this.textbox1.Text = this.button1.Text;
actionDelegate1(null,null);//【5】调用委托
}

至此完成了功能。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

其他实现了一些类似的自由控制显示等等小功能,都是通过事件和委托来实现的;所以说,C#学会并深入理解了2大神技:事件与委托,并能活学活用,C#编程技术才能说是刚刚入门;

最后,贴上完整的代码运行截图:

效果图:

源代码:

Form1:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace ParentFormDemo
{
public delegate void ActionDelegate(object sender, EventArgs e);//【1】定义委托
public partial class Form1 : Form
{
Label label1 = new Label();//Form1的字段成员变量,要放在Class里面
Form2 frm2 = new Form2();
public Form1()
{
InitializeComponent();
this.IsMdiContainer = true;//设置容器属性 this.Controls.Add(label1);
label1.Size =new Size(this.Size.Width, 50);
label1.BackColor = Color.Yellow; label1.Text ="第1步:演示了一个子窗口依附在父窗口上,这种MDI窗口模式"+
"\r\n" + "第2步:请按下按钮,观察其上方的显示框内容会显示按钮名称" +
"\r\n"+"第3步,在观察父窗口的标题栏变化"; this.Resize += Form1_Resizing;
this.ResizeEnd+= Form_ResizeEnd;
} private void Form_ResizeEnd(object sender, EventArgs e)
{
frm2.textbox1.Text = "完成";//在子窗口显示信息
frm2.textbox1.BackColor = Color.White;
}
public void Form1_Resizing(object sender, EventArgs e)
{
frm2.textbox1.Text = "正在拖拽改变主窗口大小";//在子窗口显示信息
label1.Size = new Size(this.Size.Width, 50);
frm2.textbox1.BackColor = Color.Yellow;
} private void Form1_Load(object sender, EventArgs e)
{
frm2.actionDelegate1 = ChangeTitle;//【3】绑定委托
frm2.MdiParent = this;
frm2.StartPosition = FormStartPosition.CenterScreen;//设置子窗体在父窗体中间显示
frm2.Show();
}
public void ChangeTitle(object sender, EventArgs e)
{
this.Text = DateTime.Now.ToString("HH:mm:ss .fff") + ">>子窗口的按钮被按下";
}
}
}

Form2:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace ParentFormDemo
{
public partial class Form2 : Form
{
Button button1 = new Button();
public TextBox textbox1 = new TextBox();
public ActionDelegate actionDelegate1 = null;//【2】定义委托变量
public Form2()
{
InitializeComponent();
button1.Top = 50;
button1.Text = "Say Hello";
this.Controls.Add(button1);
this.Controls.Add(textbox1); textbox1.Size = new Size( this.Width,50);
button1.Click += this.Action1;
this.Resize += this.SiziChanging;
this.ResizeEnd += this.SizeChangedEnd;
} private void SizeChangedEnd(object sender, EventArgs e)
{
this.textbox1.Text = "子窗口大小改变完成";
this.textbox1.BackColor = Color.White;
} private void SiziChanging(object sender, EventArgs e)
{
this.textbox1.BackColor = Color.Yellow;
this.textbox1.Size = new Size(this.Size.Width, 50);
this.textbox1.Text = "正在拖拽子窗口大小";
} private void Action1(object sender, EventArgs e)
{
this.textbox1.Text = this.button1.Text;
actionDelegate1(null,null);//【5】调用委托
}
}
}

Main(程序入口):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms; namespace ParentFormDemo
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

大家感兴趣的小伙伴们可以,copy到自己的工程试试啦

MDI子窗口+事件与委托的一个例程的更多相关文章

  1. DELPHI中MDI子窗口的关闭和打开

    DELPHI中MDI子窗口的关闭 和打开       Delphi中MDI子窗口的关闭方式默认为缩小而不是关闭,所以当你单击子窗口右上角的关闭按钮时会   发觉该子窗口只是最小化,而不是你预期的那样被 ...

  2. DELPHI中MDI子窗口的关闭 和打开

    Delphi中MDI子窗口的关闭方式默认为缩小而不是关闭,所以当你单击子窗口右上角的关闭按钮时会发觉该子窗口只是最小化,而不是你预期的那样被关闭.解决办法是在子窗口的OnClose事件处理过程中加入如 ...

  3. Delphi 关闭MDI子窗口

    需要在子窗口的onClose事件中吧Action = caFree; 就可以了. procedure Tfrm_aa.FormClose(Sender: TObject; var Action: TC ...

  4. VB.NET章鱼哥出品—怎样解决MDI子窗口被父窗口中的控件覆盖的问题

    近期有个网友问我这个问题,我就上网搜了下,结果非常失望.有几个在CSDN上发的求助帖.看到最后都没有找到明白的答案. 这里笔者在网上找到了API函数SetParent(),并对网上的错误进行了改动,并 ...

  5. winform MDI子窗口闪动问题(本人测试100%有效解决闪屏问题)

    将下面的代码随便放到主窗体的任何一个地方 protected override CreateParams CreateParams //解决MDI闪屏 { get { CreateParams cp ...

  6. winform MDI子窗口闪动问题

    在网上看到的 不知道什么原理但真的很实用 将下面的代码随便放到主窗体的任何一个地方 protected override CreateParams CreateParams         { get ...

  7. Delphi MDI 子窗体的创建和销毁 [zhuan]

    1.如果要创建一个mdi child,先看是否有这个child 存在,如果有,则用它,如果没有再创建 //该函数判断MDI 子窗体是否存在,再进行创建和显示function isInclude(for ...

  8. GetActiveView 返回 NULL 为 MDI 框架窗口

    blog 在 MDI 应用程序中,MDI 主框架窗口(CMDIFrameWnd) 不具有与其相关联的视图.相反,每个单独的子窗口(CMDIChildWnd)具有与之关联的一个或多个视图.因此,对 MD ...

  9. 保证相同类型的MDI子窗体只会被打开一次的方法

    本文转载:http://www.cnblogs.com/Ricky81317/archive/2008/09/17/1292443.html 看到论坛中有朋友问,如何可以保证在MDI主窗体中,同一类型 ...

  10. Silverlight子窗口(ChildWindow)传递参数到父窗口演示

    在企业级项目中,子窗口(ChildWindow)是一个常用控件,其展示方式是以弹出窗口来显示信息. 这里我将演示,子窗口传递参数到父窗口的方法.由于我的开发环境都是英文环境,所以部分中文可能显示不正常 ...

随机推荐

  1. 在 JS 中使用 canvas 给图片添加文字水印

    实现说明: 1.先通过 new Image() 载入图片: 2.图片加载成功后使用 drawImage() 将图片绘制到画布上: 3.最后使用 fillText() 函数绘制水印. 下面展示了详细用法 ...

  2. windows上安装mysql-5.6.44-winx64

    配置MySQL配置文件my.ini.datadir一般和安装目录是分开存放的 [mysqld] # 设置3306端口 port=3306 # 设置mysql的安装目录 ---这里输入你安装的文件路径- ...

  3. 基于webapi的websocket聊天室(二)

    上一篇 - 基于webapi的websocket聊天室(一) 消息超传缓冲区的问题 在上一篇中我们定义了一个聊天室WebSocketChatRoom.但是每个游客只分配了400个字节的发言缓冲区,大概 ...

  4. Hugging Face ZeroGPU 计划正式发布—提供价值一千万美元的免费共享 GPU

    在人工智能技术领域,GPU 资源一直是推动研究和应用的关键因素.然而,GPU 的成本和可用性对于许多研究人员和开发者来说却是一个显著的障碍. 在 Hugging Face,我们希望人工智能技术可以更加 ...

  5. 基于ADB Shell 实现的 Android TV、电视盒子万能遥控器 — ADB Remote ATV

    ADB Remote ATV Android TV 的遥控器,基于 ADB Shell 命令 ADB Remote ATV 是一个 Android TV 的遥控器,基于 ADB Shell 命令,泛用 ...

  6. 深入解析HashMap源码

    HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型.随着JDK(Java Developmet Kit)版本的更新,JDK1.8对HashMap底层的实现进行了优化,例如引入 ...

  7. 微信小程序预约视频号直播

    一.概述 微信小程序提供了可以唤起预约视频号直播弹窗的接口 reserveChannelsLive,该接口接收一个参数 noticeId,通过 getChannelsLiveNoticeInfo 接口 ...

  8. nginx001

    本文档版权归属:陈雷雷,仅限学习交流 QQ:370460470 blog:www.chenleilei.net Nginx服务实践 简述Nginx(nginx.org) Nginx (engine x ...

  9. Your Post Title Here

    VSCode 实时预览还需要执行 Markdown: Open Preview to the Side 命令来实现. 在命令窗口输入 Markdown: Open Preview to the Sid ...

  10. Java中编译异常与运行异常的区别

    编译期异常和运行期异常的区别 编译期异常和运行期异常的区别如下 异常处理要求不同:编译期异常(也称为检测异常checked Exception)要求在代码中显式地处理(使用try-catch或者thr ...