C# Windows窗体间消息传递的问题

--

提出Windows窗体间消息传递的问题:如何根据子窗体的状态更改父窗体的状态?如双击DataGridView的行记录后弹出修改该行记录的子窗体,在修改完数据后希望DataGridView数据刷新,这就需要子窗体通知父窗体刷新数据!

考虑在子窗体上移动鼠标,将子窗体鼠标的坐标传递给父窗体的标题栏,如何实现?反过来在父窗体上移动鼠标,如何传递给子窗体?

经典的做法为方法回调,在父窗体类中注册子窗体的MouseMove事件调用父窗体的Method直接修改标题栏;当然我们也可以将父窗体的对象指针船体给子窗体对象的tag,然后在子窗体的MouseMove事件中将tag转换为父窗体对象,然后修改其标题栏文本。回调方案不会破坏程序的逻辑,也不会破坏程序的封装;而tag对象的传递方式必须要public公开tag对象实例的方法和属性才可以!

下面分别示例两种方式实现,考虑父窗体修改子窗体如何实现?!

//target: implement mouse move on child window, call father Window's Method

//implement: before Show the ChildWindow, give EventHandler to the childWindow

//and pick up a local method to the EvenHandler The Callback Method!!!!

using System;

using System.Windows.Forms;

namespace infoFromWindows

{

// TypDefName: infoFromWindows.frmFather (02000003)

// Flags : [NotPublic] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit] (00100000)

// Extends : 01000001 [TypeRef] System.Windows.Forms.Form

class frmFather : System.Windows.Forms.Form

{

private Button btnAbout;

private frmFather()

{

btnAbout = new Button();

btnAbout.ForeColor = System.Drawing.Color.Green;

btnAbout.Text="&About Me";

btnAbout.Click += new System.EventHandler(this.btnAboutClick);

this.Width=400;

this.Controls.Add(btnAbout);

}

//this method will be called from child window WHEN mouse move on Child Window

//notice here, private void ... question: who is the "sender"?

private void SetChildPosToFather(object sender, MouseEventArgs e)

{

string strPos = string.Format( "Child Mouse POS:({0},{1})",e.X,e.Y);

this.Text = strPos;

Form about = (Form) sender;

about.Width=400;

about.Text=string.Format( "Current Mouse POS:({0},{1})",e.X,e.Y);

}

private void btnAboutClick(object sender,System.EventArgs e)

{

Form about = new Form();

//here, we give the child window a EventHandler to call local Method!!!

about.MouseMove += new MouseEventHandler(SetChildPosToFather);

about.Show();

}

private static void Main()

{

frmFather father = new frmFather();

Application.Run(father);

}

}

}

tag传递

using System;

using System.Windows.Forms;

using System.Collections.Generic;

namespace infoFromWindows

{

public class frmAbout : Form

{

public frmAbout()

{

this.Text="I'm Child Window";

this.MouseMove += new MouseEventHandler(changeFatherText);

}

private void changeFatherText(object sender, MouseEventArgs e)

{

frmFather father = (frmFather) this.Tag;

father.Text = string.Format( "Child Mouse POS:({0},{1})",e.X,e.Y);

}

}

// TypDefName: infoFromWindows.frmFather (02000003)

// Flags : [NotPublic] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit] (00100000)

// Extends : 01000001 [TypeRef] System.Windows.Forms.Form

class frmFather : System.Windows.Forms.Form

{

private Button btnAbout;

private void btnAboutClick(object sender,System.EventArgs e)

{

frmAbout about = new frmAbout();

about.Tag = this;

//here,we transfer current Form POINT to "about" window,

//then from "about" window

//we can access current Form any PUBLIC method and properties.

about.Show();

}

public frmFather()

{

btnAbout = new Button();

btnAbout.ForeColor = System.Drawing.Color.Green;

btnAbout.Text="&About Me";

btnAbout.Click += new System.EventHandler(this.btnAboutClick);

this.Width=400;

this.Controls.Add(btnAbout);

}

public static void Main()

{

frmFather father = new frmFather();

Application.Run(father);

}

}

}

利用回调实现双窗口通讯,尝试开启多个窗口一起测试

using System;

using System.Windows.Forms;

using System.Collections.Generic;

namespace infoFromWindows

{

public class frmAbout : Form

{

public frmAbout()

{

this.Text="I'm Child Window";

}

//public, called by father window through MouseMove Event

public void ChangeColor(object sender, MouseEventArgs e)

{

this.BackColor = System.Drawing.Color.FromArgb(e.X,e.Y,0);

}

}

// TypDefName: infoFromWindows.frmFather (02000003)

// Flags : [NotPublic] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit] (00100000)

// Extends : 01000001 [TypeRef] System.Windows.Forms.Form

class frmFather : System.Windows.Forms.Form

{

private Button btnAbout;

public frmFather()

{

btnAbout = new Button();

btnAbout.ForeColor = System.Drawing.Color.Green;

btnAbout.Text="&About Me";

btnAbout.Click += new System.EventHandler(this.btnAboutClick);

this.Height=255;

this.Width=255;

this.MaximizeBox = false;

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;

this.Controls.Add(btnAbout);

}

private void GetChildPosCallFromFather(object sender,MouseEventArgs e)

{

this.Text=string.Format("({0},{1})",e.X,e.Y);

}

private void btnAboutClick(object sender,System.EventArgs e)

{

frmAbout about = new frmAbout();

//here,we transfer current Form POINT to "about" window,

//then from "about" window

//we can access current Form any PUBLIC method and properties.

about.Show();

about.MouseMove += new MouseEventHandler(GetChildPosCallFromFather);

this.MouseMove += new MouseEventHandler(about.ChangeColor);

}

public static void Main()

{

frmFather father = new frmFather();

Application.Run(father);

}

}

}