網站首頁 編程語言 正文
一、前言
我們在做Winform窗體程序開發的時候,會經常遇到窗體之間相互傳值。假設有下面的一個場景:一個主窗體和一個子窗體,點擊主窗體上面的按鈕給子窗體傳值,并在子窗體上面顯示出來,一般會有如下幾種方式實現。
二、公共屬性
我們可以在子窗體里面定義一個公共的屬性,然后在父窗體里面給公共屬性賦值,這樣可以實現窗體之間傳值,子窗體代碼如下:
using System; using System.Windows.Forms; namespace DelegateDemo { public partial class frmChild : Form { public frmChild() { InitializeComponent(); } // 定義一個公共屬性,接收傳遞的值 public string strMessage { get; set; } ////// 窗體加載 /// /// /// private void frmChild_Load(object sender, EventArgs e) { // 將接收到的值顯示在窗體上 this.lblMessage.Text = strMessage; } } }
父窗體代碼:
using System; using System.Windows.Forms; namespace DelegateDemo { public partial class frmParent : Form { public frmParent() { InitializeComponent(); } ////// 單擊事件 /// /// /// private void btn_Value_Click(object sender, EventArgs e) { frmChild child = new frmChild(); // 給窗體的公共屬性賦值 child.strMessage = this.txtMessage.Text.Trim(); // 顯示子窗體 child.Show(); } } }
這種方式有一個缺點:屬性需要設置為public,不安全。
三、公共方法
我們還可以在子窗體里面定義一個方法,通過調用方法傳值,子窗體代碼如下:
using System; using System.Windows.Forms; namespace DelegateDemo { public partial class frmChild : Form { public frmChild() { InitializeComponent(); } // 定義一個公共屬性,接收傳遞的值 //public string strMessage { get; set; } // 定義屬性為private private string strMessage { get; set; } ////// 給私有屬性賦值 /// /// public void SetText(string strText) { strMessage = strText; } ////// 窗體加載 /// /// /// private void frmChild_Load(object sender, EventArgs e) { // 將接收到的值顯示在窗體上 this.lblMessage.Text = strMessage; } } }
父窗體代碼:
using System; using System.Windows.Forms; namespace DelegateDemo { public partial class frmParent : Form { public frmParent() { InitializeComponent(); } ////// 單擊事件 /// /// /// private void btn_Value_Click(object sender, EventArgs e) { #region 調用公共屬性賦值 //frmChild child = new frmChild(); //// 給窗體的公共屬性賦值 //child.strMessage = this.txtMessage.Text.Trim(); //// 顯示子窗體 //child.Show(); #endregion #region 調用方法賦值 frmChild child = new frmChild(); // 給窗體的公共屬性賦值 child.SetText(this.txtMessage.Text.Trim()); // 顯示子窗體 child.Show(); #endregion } } }
這種方式同樣也有缺點:屬性雖然是private的了,但是方法還是public的。
四、委托
上述兩種方式都是不安全,下面我們使用委托來實現窗體之間傳值。
1、定義一個委托
我們在主窗體里面定義一個有參無返回值的委托:
// 定義一個有參無返回值的委托 private delegate void SendMessage(string strMessage);
2、實例化一個此委托類型的事件
在父窗體里面定義一個委托類型的事件:
// 定義一個委托類型的事件 public event SendMessage sendMessageEvent;
委托與事件的關系,事件相對于委托更安全,更低耦合。委托是一個類型,事件是委托類型的一個實例。
3、定義要執行的方法
這里其實就是在子窗體里面定義一個給控件賦值的方法:
////// 給控件賦值的方法 /// /// public void SetValue(string strValue) { this.lblMessage.Text = strValue; }
4、將方法綁定到事件
frmChild child = new frmChild(); // 將方法綁定到事件上 sendMessageEvent += new SendMessage(child.SetValue); // 也可以使用下面的簡寫形式 // sendMessageEvent += child.SetValue; child.Show();
5、觸發委托
在按鈕的點擊事件里面觸發委托:
if(sendMessageEvent!=null) { sendMessageEvent.Invoke(this.txtMessage.Text.Trim()); }
上面的代碼中使用的是自定義的委托,我們也可以使用.Net 框架里面自帶的Action泛型委托:
using System; using System.Windows.Forms; namespace DelegateDemo { public partial class frmParent : Form { // 定義一個有參無返回值的委托 public delegate void SendMessage(string strMessage); // 定義一個委托類型的事件 public event SendMessage sendMessageEvent; public event ActionactionEvent; public frmParent() { InitializeComponent(); } /// /// 單擊事件 /// /// /// private void btn_Value_Click(object sender, EventArgs e) { #region 調用公共屬性賦值 //frmChild child = new frmChild(); //// 給窗體的公共屬性賦值 //child.strMessage = this.txtMessage.Text.Trim(); //// 顯示子窗體 //child.Show(); #endregion #region 調用方法賦值 //frmChild child = new frmChild(); //// 給窗體的公共屬性賦值 //child.SetText(this.txtMessage.Text.Trim()); //// 顯示子窗體 //child.Show(); #endregion #region 通過委托傳值 //frmChild child = new frmChild(); //// 將方法綁定到事件上 //// sendMessageEvent += new SendMessage(child.SetValue); //// 也可以使用下面的簡寫形式 //sendMessageEvent += child.SetValue; //child.Show(); #endregion #region 使用Action frmChild child = new frmChild(); // 將方法綁定到事件上 actionEvent += child.SetValue; child.Show(); #endregion // 使用自定義委托 //if (sendMessageEvent!=null) //{ // sendMessageEvent.Invoke(this.txtMessage.Text.Trim()); //} // 使用Action委托 if (actionEvent != null) { actionEvent.Invoke(this.txtMessage.Text.Trim()); } } } }
完整示例代碼:https://github.com/jxl1024/FromPassValueDemo
原文鏈接:https://www.cnblogs.com/dotnet261010/p/12301683.html
相關推薦
- 2022-08-28 C#中類的使用教程詳解_C#教程
- 2022-11-20 C++遞歸算法處理島嶼問題詳解_C 語言
- 2022-08-03 使用Go構建一款靜態分析工具Owl詳解_Golang
- 2022-10-10 VMware?Workstation與Device/Credential?Guard不兼容的解決_V
- 2021-12-02 C語言中幾種常量的認識和理解_C 語言
- 2022-10-10 C++?STL標準庫std::vector擴容時進行深復制原因詳解_C 語言
- 2023-01-17 Golang?map實現原理淺析_Golang
- 2023-03-25 Python?Flask-Login模塊使用案例詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支