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#自定義消息。
消息發送方
一、引入命名空間
- using System.Runtime.InteropServices;
二、消息定義
-
-
- public const int USER = 0x500;
-
- public const int MYMESSAGE = USER + 1;
三、自定義結構體
- public struct My_lParam
-
- {
-
- public int i;
-
- public string s;
-
- }
四、重寫消息發送函數
-
-
- [DllImport("User32.dll", EntryPoint = "SendMessage")]
-
- private static extern int SendMessage(
-
- IntPtr hWnd,
-
- int Msg,
-
- int wParam,
-
- ref My_lParam lParam
-
- );
五、獲取窗體句柄的函數引入
- [DllImport("User32.dll", EntryPoint = "FindWindow")]
-
- private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
六、消息發送
- IntPtr ptr = FindWindow(null, "Form1");
-
-
-
- My_lParam m = new My_lParam();
-
- m.s = textBox1.Text;
-
- m.i = m.s.Length;
-
- SendMessage(ptr, MYMESSAGE, 1, ref m);
消息接收方
一、引入命名空間
- using System.Runtime.InteropServices;
二、消息定義
-
-
- public const int USER = 0x500;
-
- public const int MYMESSAGE = USER + 1;
三、重寫窗體的消息處理函數
-
-
- protected override void DefWndProc(ref Message m)
-
- {
-
- switch (m.Msg)
-
- {
-
-
-
- case MYMESSAGE:
-
- Form2.My_lParam ml = new Form2.My_lParam();
-
- Type t = ml.GetType();
-
- ml = (Form2.My_lParam)m.GetLParam(t);
-
- label1.Text = ml.s;
-
- break;
-
- default:
-
- base.DefWndProc(ref m);
-
- break;
-
- }
-
- }
如上,我們就實現了一個C#自定義消息的程序,貼上一個程序下載地址:http://download.csdn.net/detail/bdstjk/2707423。
不知道大家在C#中有沒有更好的實現方法。
經過研究,C#確實有方法可以更簡單的實現這個功能,請看C# 委托實例(跨窗體操作控件)
最后再給大家介紹一種最簡單的C#跨窗體操作
程序運行示意: