【WinForm】—窗體之間傳值的幾種方式


前言

    小編最近維護一個Winfrom窗體,是項目中CS端的主窗體,很多子窗體需要從主窗體獲取值,同時子窗體還需要給主窗體回傳值,下面來給大家介紹一下。

正文

    本文中以主窗體為frmMain,子窗體為frmGroup ,兩窗體之間的傳值來做示例。

方式一: 使用公共靜態變量傳值

主窗體frmMain中代碼

public partial class frmMain : Form
{
 //聲明工位ID 為公共靜態變量
 public static string terminalID = "";
 //給靜態變量賦值
 terminalID = "q13bh01-bh12";
 }

子窗體frmGroup中代碼

 private void frmGroup_Load(object sender, EventArgs e)
{
    this.txtTerminalID.Text= frmMain.terminalID.Trim(); 
    //可以再賦值給靜態成員,方便其他窗體調用
    frmMain.terminalID = "q13bh01-bh11";
}

特點 : 雙向傳值,實現簡單 
缺點: 靜態變量在類加載的時候分配內存,存儲於方法區,一般不會被銷毀,在系統不夠內存情況下會自動回收靜態內存,這樣就會引起訪問全局靜態錯誤。

方式二: 使用公共變量傳值

主窗體frmMain中代碼

public partial class frmMain : Form
{
 //聲明工位ID 為公共變量
 public string terminalID = "";
 //給變量賦值
 terminalID = "q13bh01-bh12";
 //單擊‘行為’按鈕的時候會給窗體傳值
  private void btnGroup_Click(object sender, EventArgs e)
        {
            frmGroup frmGro = new  frmGroup();
            //變量傳值 ,注意順序寫在ShowDialog()方法之前
            frmGro .stationID = this.terminalID;
            frmGro .ShowDialog();
        }
 }

子窗體frmGroup中代碼

  public partial class frmGroup : Form
  {
    //定義公共屬性
    public string stationID = "";
  }

特點 : 單向傳值,只能主窗體給子窗體傳值,實現簡單

方式三: 使用委托傳值

先來看子窗體frmGroup中代碼

namespace Siemens.Simatic.GUIClient.MESClient
{
    //1、聲明一個委托
    public delegate void setTextValue(string textValue,bool flag);
    public partial class frmGroup : Form
    {
        //2、聲明一個委托類型的事件
         public event setTextValue setFormTextValue;
         public string groupName = "";
         public bool flagBtnGroup = false;  
         public frmGroup()
         {
           InitializeComponent();
         }
          //輪詢‘行為’按鈕(相當於按鈕單擊事件)
          private void tmrBtn_Tick(object sender, EventArgs e)
          {
            if (sender is ButtonX) {
                ButtonX butX = (ButtonX)sender;//判斷觸發事件的是不是Button
                groupName = butX.Text.Trim();
                flagBtnGroup = true;
                //3、准備要回傳的數據。  
                setFormTextValue(this.groupName.Replace(" ", ""), this.flagBtnGroup );
                this.Close();
                return;
            } 
        }

 

主窗體frmMain中代碼

  private void btnGroup_Click(object sender, EventArgs e)
        {
            frmGroup frmGro = new  frmGroup();
             //4、初始化事件  
            frmGro .setFormTextValue += new setTextValue(frmGro _setFormTextValue);
            //變量傳值 ,注意順序寫在ShowDialog()方法之前
            frmGro .stationID = this.terminalID;
            frmGro .ShowDialog();
        }
        //5、事件具體實現
         public void frmGro _setFormTextValue(string textValue,bool flag)
        { 
            this.newGroupName = textValue;
            this.flagBtnGroup = flag;
            if (!string.IsNullOrEmpty(newGroupName))
            {
                 ……
            }
         }
 

特點 :適合子窗體數據實時回傳父窗體。

叨叨兩句

    項目中父窗體向子窗體傳值傳的是固定值,用的是第一種方式,子窗體向父窗體傳值傳的是變化的值,用的是第三種方式,第三種方式為我解決了一個大麻煩。

總結

    感謝您的閱讀,窗體傳值有好多種方法,構造參數參數傳值、公共屬性傳值等,各種場景下找到適合需求的最好,希望為小編提出寶貴意見!

 

 

1. 登陸邏輯

  • FrmMain 為主窗體(啟動窗體)
  • FrmLogin 為登陸窗體

在“主窗體”中使用ShowDialog()方法顯示“登陸窗體”,並通過“登陸窗體”的DialogResult告知“主窗體”是否登陸成功。

1.1 主窗體:

private void FrmMain_Load(object sender, EventArgs e)
{
    FrmLogin frm = new FrmLogin();
    if (frm.ShowDialog() == DialogResult.OK)
    {
        // 執行主窗體的一些初始化內容
    }
    else
    {
        this.Close();    // 關閉主窗體
    }
}

1.2 登陸窗體:

private vode btn_Login_Click(object sender, EventArgs e)
{
    this.DialogResult = DialogResult.OK;
}

2. 窗體間的數據傳遞

“登陸窗體”在執行完畢后,需要將登陸用的信息傳遞給“主窗體”,其傳遞的過程就是“暫時”將用戶信息存在“主窗體”可以獲取的“地方”,根據“地方”不同可以有一下幾種方案。

新建 User.cs

public class User {
    public string username;
    public User(string username)
    {
        this.username = username;
    }
}

2.1 將數據暫存在“登陸窗體”的Tag屬性上

2.1.1 登陸窗體:

private vode btn_Login_Click(object sender, EventArgs e)
{
    this.Tag = new User('rianman');
    this.DialogResult = DialogResult.OK;
}

2.1.2 主窗體:

private void FrmMain_Load(object sender, EventArgs e)
{
    FrmLogin frm = new FrmLogin();
    if (frm.ShowDialog() == DialogResult.OK)
    {
        User user = frm.Tag as User;    // 此處獲取“登陸窗體”傳遞過來的數據
    }
    else
    {
        this.Close();    // 關閉主窗體
    }
}

2.2 將數據暫存在“主窗體”的Tag屬性上

2.2.1 登陸窗體:

private vode btn_Login_Click(object sender, EventArgs e)
{
    FrmMain main this.Owner as FrmMain;
    main.Tag = new User("rainman");
    this.DialogResult = DialogResult.OK;
}

2.2.2 主窗體:

private void FrmMain_Load(object sender, EventArgs e)
{
    FrmLogin frm = new FrmLogin();
    if (frm.ShowDialog() == DialogResult.OK)
    {
        User user = this.Tag as User;    // 此處獲取“登陸窗體”傳遞過來的數據
    }
    else
    {
        this.Close();    // 關閉主窗體
    }
}

2.3 將數據暫存在類的“靜態成員”上

2.3.1 新建Context.cs

public class Context
{
    public static User LoginUser = null;
}

2.3.2 登陸窗體:

private vode btn_Login_Click(object sender, EventArgs e)
{
    Context.LoginUser = user;
    this.DialogResult = DialogResult.OK;
}

2.3.3 主窗體:

private void FrmMain_Load(object sender, EventArgs e)
{
    FrmLogin frm = new FrmLogin();
    if (frm.ShowDialog() == DialogResult.OK)
    {
        User user = Context.LoginUser;    // 此處獲取“登陸窗體”傳遞過來的數據
    }
    else
    {
        this.Close();    // 關閉主窗體
    }
}

2.4 將數據暫存在“主窗體”的特定屬性上

2.4.1 登陸窗體:

private vode btn_Login_Click(object sender, EventArgs e)
{
    FrmMain main = this.Owner as FrmMain;
    main.LoginUser = new User("rainman");
    this.DialogResult = DialogResult.OK;
}

2.4.2 主窗體:

public user LoginUser { get; set; }
 
private void FrmMain_Load(object sender, EventArgs e)
{
    FrmLogin frm = new FrmLogin();
    if (frm.ShowDialog() == DialogResult.OK)
    {
        User user = this.LoginUser;    // 此處獲取“登陸窗體”傳遞過來的數據
    }
    else
    {
        this.Close();    // 關閉主窗體
    }
}

 

 

 

三-----------------------------------------------

在窗體2中添加如下代碼:

  View Code

在窗體1中添加如下代碼:

  View Code

這種可以實現子窗體和父窗體的相互傳值。

第二種:委托事件傳值

1.在窗體2中命名空間下先定義一個委托:public delegate void ChangeHandleText(string str);//帶參數

2.定義一個事件:public event ChangeHandleText changetext;//定義事件

3.將事件與委托關聯起來:Form2 f=new Form2();  f.changetext+=new ChangeHandleText(Change_text);//關鍵

form2代碼:

  View Code

form1代碼

  View Code

第三種:泛型委托和Lambda表達式結合

簡單介紹下Lambda表達式:“Lambda表達式”是一種匿名函數,是一種高效的類似於函數式編程的表達式,Lambda簡化了開發中需要編寫的代碼量。它可以包含表達式和語句,並且可用於創建委托或表達式目錄樹類型,支持帶有可綁定到委托或表達式樹的輸入參數的內聯表達式。所有Lambda表達式都使用Lambda運算符=>,該運算符讀作“goes to”。Lambda運算符的左邊是輸入參數(如果有),右邊是表達式或語句塊。Lambda表達式x=>x*x讀作“x goes  to x times x”。可以將此表達式分配給委托類型。如下圖

  View Code

言歸正傳。

窗體2代碼

  View Code

窗體1代碼

復制代碼
public partial class Form1 : Form
 8     {
 9         public Form1()
10         {
11             InitializeComponent();
12         }
13 
14         private void button1_Click(object sender, EventArgs e)
15         {
16             Form2 f2 = new Form2();
17             f2.ChangeText = (str) => textBox1.Text = str;//用lambda表達式實現,這句話必須放在f2.ShowDialog();前面
18             f2.ShowDialog();            
19         }
20     }
復制代碼
public partial class Form1 : Form
 8     {
 9         public Form1()
10         {
11             InitializeComponent();
12         }
13 
14         private void button1_Click(object sender, EventArgs e)
15         {
16             Form2 f2 = new Form2();
17             f2.ChangeText = (str) => textBox1.Text = str;//用lambda表達式實現,這句話必須放在f2.ShowDialog();前面
18             f2.ShowDialog();            
19         }
20     }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM