C#窗体之间传递消息和事件

来源:互联网 发布:unity3d 显示3d模型 编辑:程序博客网 时间:2024/05/16 03:48

     C# WinForm编程中,你是否遇到过这样的问题,在主窗口Form1中点击按钮,弹出一个子窗口Form2,你希望在Form2中调用Form1的函数,改变Form1的显示,却发现Form1不听话,达不到预期效果。有的人说我调试了的,那段函数确实执行了,怎么还是没有显示呢?

案例:

在winform中,我在点击from1的一个按钮,弹出from3执行一个函数,其实form3就是弹出一个自制的密码输入框但是呢。然后我再from3中调用
    if (password == PassWord)
            {
                comfirm = true;
                form1.updateMac(row, col);
                this.Close();
            }
在updateMac(row,col)中我有个dataGridView1.Rows[row].Cells[col].Style.BackColor = Color.Green;但是颜色死活不变,特别奇怪,放在form1的其他函数里就能变,就是凡在这个form3调用form1的函数里,不能变色,是为什么啊

 

      其实Form1不听话是必然的,你在Form2中new Form1(),这样新新建了一个窗口对象,和本身的父窗口是两个不同的对象,你改变对象A怎么能期望对象B也变化呢?

      那有没有什么办法可以实现我们预期的效果呢?

      有的,那就是利用win32函数,使用自定义消息,做C++的人对这个应该不陌生,下面就给大家讲一下C#自定义消息。

消息发送方

一、引入命名空间

[csharp] view plaincopy
  1. using System.Runtime.InteropServices;  

二、消息定义

[csharp] view plaincopy
  1. //自定义的消息  
  2.   
  3. public const int USER = 0x500;  
  4.   
  5. public const int MYMESSAGE = USER + 1;  

 

三、自定义结构体

[csharp] view plaincopy
  1. public  struct My_lParam  
  2.   
  3.        {  
  4.   
  5.            public int i;  
  6.   
  7.            public string s;  
  8.   
  9.        }  

 

四、重写消息发送函数

[csharp] view plaincopy
  1. //消息发送API  
  2.   
  3. [DllImport("User32.dll", EntryPoint = "SendMessage")]  
  4.   
  5. private static extern int SendMessage(  
  6.   
  7. IntPtr hWnd,        // 信息发往的窗口的句柄  
  8.   
  9. int Msg,            // 消息ID  
  10.   
  11. int wParam,         // 参数1  
  12.   
  13. ref My_lParam lParam  
  14.   
  15. );  


 

五、获取窗体句柄的函数引入

[csharp] view plaincopy
  1. [DllImport("User32.dll", EntryPoint = "FindWindow")]  
  2.   
  3. private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);  

 

六、消息发送

[csharp] view plaincopy
  1. IntPtr ptr = FindWindow(null"Form1");//获取接收消息的窗体句柄,这个地方有一点我们要注意Form1必须唯一,否则windows无法将消息正确发送  
  2.   
  3. //消息构建  
  4.   
  5. My_lParam m = new My_lParam();  
  6.   
  7. m.s = textBox1.Text;  
  8.   
  9. m.i = m.s.Length;  
  10.   
  11. SendMessage(ptr, MYMESSAGE, 1, ref m);//发送消息  


 

消息接收方

一、引入命名空间

[csharp] view plaincopy
  1. using System.Runtime.InteropServices;  

 

二、消息定义

[csharp] view plaincopy
  1. //自定义的消息  
  2.   
  3. public const int USER = 0x500;  
  4.   
  5. public const int MYMESSAGE = USER + 1;  

 

三、重写窗体的消息处理函数

      

[csharp] view plaincopy
  1. ///重写窗体的消息处理函数DefWndProc,从中加入自己定义消息 MYMESSAGE 的检测的处理入口  
  2.   
  3.        protected override void DefWndProc(ref Message m)  
  4.   
  5.        {  
  6.   
  7.            switch (m.Msg)  
  8.   
  9.            {  
  10.   
  11.                //接收自定义消息MYMESSAGE,并显示其参数  
  12.   
  13.                case MYMESSAGE:  
  14.   
  15.                    Form2.My_lParam ml = new Form2.My_lParam();  
  16.   
  17.                    Type t = ml.GetType();  
  18.   
  19.                    ml = (Form2.My_lParam)m.GetLParam(t);  
  20.   
  21.                    label1.Text = ml.s;  
  22.   
  23.                    break;  
  24.   
  25.                default:  
  26.   
  27.                    base.DefWndProc(ref m);  
  28.   
  29.                    break;  
  30.   
  31.            }  
  32.   
  33.        }  


 如上,我们就实现了一个C#自定义消息的程序,贴上一个程序下载地址:http://download.csdn.net/detail/bdstjk/2707423。

不知道大家在C#中有没有更好的实现方法。

经过研究,C#确实有方法可以更简单的实现这个功能,请看C# 委托实例(跨窗体操作控件)

 

最后再给大家介绍一种最简单的C#跨窗体操作

 

程序运行示意:

 

现在给大家介绍一种最简单的跨窗体操作

WinForm的窗体是一个类,C#的类是引用类型,那么我们应该可以将WinForm窗体类进行传递,那不就可以进行操作了么?

 

效果描述:

有三个窗体然后顺序分别是

(1)点击第一个窗体中的按钮弹出第二个窗体,隐藏第一个窗体

(2)第二个窗体到一定时间弹出第三个窗体

(3)点击第三个窗体的按钮关闭第三个和第二个窗体,弹出第一个窗体

 

From1

[csharp] view plaincopy
  1. using System;  
  2. using System.Windows.Forms;  
  3.   
  4. namespace WindowsFormsApplication1  
  5. {  
  6.     public partial class Form1 : Form  
  7.     {  
  8.         public Form1()  
  9.         {  
  10.             InitializeComponent();  
  11.         }  
  12.   
  13.         private void 打开form2隐藏form1_Click(object sender, EventArgs e)  
  14.         {  
  15.             Form2 f = new Form2();  
  16.             f.fatherForm = this;  
  17.             f.Show();  
  18.             this.Hide();  
  19.         }  
  20.     }  
  21. }  


 

Form2

[csharp] view plaincopy
  1. using System;  
  2. using System.Windows.Forms;  
  3.   
  4. namespace WindowsFormsApplication1  
  5. {  
  6.     public partial class Form2 : Form  
  7.     {  
  8.         public Form2()  
  9.         {  
  10.             InitializeComponent();  
  11.         }  
  12.   
  13.         public Form1 fatherForm;  
  14.   
  15.         private void 打开from3_Click(object sender, EventArgs e)  
  16.         {  
  17.             Form3 f = new Form3();  
  18.             f.fatherForm = this;  
  19.             f.Show();  
  20.         }  
  21.     }  
  22. }  


 

Form3

[csharp] view plaincopy
  1. using System;  
  2. using System.Windows.Forms;  
  3.   
  4. namespace WindowsFormsApplication1  
  5. {  
  6.     public partial class Form3 : Form  
  7.     {  
  8.         public Form3()  
  9.         {  
  10.             InitializeComponent();  
  11.         }  
  12.   
  13.         public Form2 fatherForm;  
  14.   
  15.         private void 关闭form3from2显示from1_Click(object sender, EventArgs e)  
  16.         {  
  17.             fatherForm.fatherForm.Show();  
  18.             fatherForm.Close();  
  19.             this.Close();  
  20.         }  
  21.   
  22.     }  
  23. }  

     

0 0