【问题标题】:Passing value from winform 2 to winform for process将值从 winform 2 传递到 winform 进行处理
【发布时间】:2013-10-08 07:44:04
【问题描述】:

我有两个winform FormAFormB,当我点击FormA中的按钮时,FormB就会启动。

FormB 有一些按钮,每个按钮都分配了一些值,当我单击任何按钮时,分配给该表单的值必须传递给我需要处理的 formA,但两个 Form 都必须处于活动状态。

以下代码附加到启动formB的formA按钮

            FormA bar = new FormA ("Login");
            bar = this;
            FormB pad = new FormB (ref bar);
            pad.ShowDialog();
            MessageBox.Show(this.getValue.ToString());

问题是我无法读取在 FormB 按钮中单击的值,直到我关闭 formB 屏幕。我正在寻找某种方式将值委托给 FormA 进行处理。

我的 FormB 看起来像,

   FormA s = null;
    string txtInput = String.Empty;

    public FormB (ref FormA form1handle)
    {
       InitializeComponent();
        s = form1handle;
    }

    public string getFormBValue {
        get { return txtInput; }
    }

 private void Dial1_Click(object sender, EventArgs e)
    {
        //txtInput = Dial1.Text;
        s.getValue = Dial1.Text;
        MessageBox.Show(s.getValue.ToString());           
    }

PS:使用 FormB 我正在尝试实现一个电话拨号盘,它将用于传递 DTMF 输入。

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    对于您描述的场景,我将使用您的FormB 中的EventHandler Delegate 触发一个由您的FormA 监控的event

    FormB(我简称Form2)

    namespace WindowsFormsApplication
    {
        using System;
        using System.Windows.Forms;
    
        public partial class Form2 : Form
        {
            public EventHandler<MyEventArgs> MyEventHandler;
    
            public Form2()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                var eventArgs = new MyEventArgs()
                {
                    TriggeredDateTime = DateTime.UtcNow,
                    Value = 5
                };
    
                OnMyEventHandler(eventArgs);
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                var eventArgs = new MyEventArgs()
                {
                    TriggeredDateTime = DateTime.UtcNow,
                    Value = 10
                };
    
                OnMyEventHandler(eventArgs);
            }
    
            private void OnMyEventHandler(MyEventArgs args)
            {
                var handler = MyEventHandler;
                if (handler != null)
                {
                    handler(this, args);
                }
            }
        }
    
        public class MyEventArgs : EventArgs
        {
            public DateTime TriggeredDateTime { get; set; }
            public int Value { get; set; }
        }
    }
    

    FormA(我简称Form1)

    namespace WindowsFormsApplication
    {
        using System.Windows.Forms;
    
        public partial class Form1 : Form
        {
            private Form2 form2;
    
            public Form1()
            {
                InitializeComponent();
    
                form2 = new Form2();
                form2.MyEventHandler += Form2EventHandler;
    
            }
    
            public void Form2EventHandler(object sender, MyEventArgs args)
            {
                MessageBox.Show(string.Format("Received value: {0}", args.Value));
            }
    
            private void button1_Click(object sender, System.EventArgs e)
            {
                form2.ShowDialog();
            }
        }
    }
    

    我已经省略了设计代码,因为它很冗长,但是,您可以从上面的示例中看到 FormB (Form2) 有两个按钮控件,FormA (Form1) 有一个按钮控件。

    Form2 公开一个EventHandler 订阅的Form1,当按下Form2 中的Button 时,会创建一个MyEventArgs 的实例,该实例存储您要发送到Form1 的值(连同一个 DateTime 值作为一个细节)和 OnMyEventHandler 委托被提出。 Form1 然后检测到事件已引发,Form2EventHandler 处理该事件。

    如果您愿意,EventHandler 委托方法也可以与其他控件一起使用。您可以通过Form2 上的多个TextBox 控件将MyEventArgs 更改为拥有任意数量的Properties,如果您愿意,可以按下Button 控件。

    【讨论】:

    • 我正在寻找这样的东西。我会尽快测试并更新。
    • 当我声明 public EventHandler MyEventHandler;我得到这个错误。 "类型 'FormA .FormB.MyEventArgs' 不能用作泛型类型或方法 'System.EventHandler' 中的类型参数 'TEventArgs'"
    • 这是由 MyEventArgs 类未明确派生自 EventArgs 引起的。 .NET 4 要求您显式地从 EventArgs 派生,.NET 4.5(我在下面构建了我的示例)不需要。我已经更新了我的示例,让Form2 显示源自EventArgsMyEventArgs
    • 我应该更明确一点,.NET 4 及更早版本要求您明确派生自 EventArgs。我之前所做的更新仍然可以在 .NET 3.5 下运行。
    • 我已经相应地修改了我的代码,但我仍然遇到同样的错误。 类型“FormA .FormB.MyEventArgs”不能用作泛型类型或方法“System.EventHandler中的类型参数“TEventArgs”
    【解决方案2】:

    在表单 B 中添加一个隐藏文本框,并在表单 A 中添加一个方法 SetChildFromValueToParent,当表单 B 中隐藏文本框的值发生更改时,该方法会被调用。基本上对于表单 B 中的按钮客户端事件,您必须将按钮值设置为表单 B 中的隐藏文本框。

    将以下逻辑添加到您的A 按钮单击,这将打开B

    private void button1_Click(object sender, EventArgs e)
    {
        B childForm = new B();
    
        //Find the textbox control in the child form
        Control[] controls = childForm.Controls.Find("textBox", true);
    
        if (null != controls[0])
        {
            //Bind the method in the parent form to child form text control's TextChanged event
            controls[0].TextChanged += new System.EventHandler(SetChildFromValueToParent);
        }
    
        childForm.ShowDialog();
    }
    

    将以下方法添加到您的From A

      private void SetChildFromValueToParent(object obj, EventArgs args)
            {
                 //Read the child form's hidden control value and set it to parent form
                 B from2 = new B();
                 string value =  ((TextBox)form2.Controls["textBox1"]).Text;            
            }
    

    【讨论】:

    • 我尝试按照您的建议更新代码。但是当我单击 FormA 中的按钮启动 FormB 时,整个应用程序崩溃了。
    • 您是否在表单 B 中添加了一个名为文本框的隐藏文本框。这一行需要 Control[] controls = childForm.Controls.Find("textBox", true);
    • 是的,我做到了,ToolStripTextBox 文本框 = new ToolStripTextBox()。我也试过 TextBox 也没用。
    • 您必须向表单 B 添加一个文本框并将可见设置为 False 并在 Controls.Find("textBox", true); 中给出该文本框的名称;和 ((TextBox)form2.Controls["textBox1"]).Text;
    【解决方案3】:

    您可以在 FormB 中创建一些公共属性并将它们设置在该表单中。然后在 FormA 中使用这些属性来获取数据。这是示例(假设您在 FormB 中有“关闭”按钮和文本框):

    public partial class FormB : Form
    {
       public string PhoneNumber { get; private set; }
    
       private void buttonClose_Click(object sender, EventArgs e)
       {
           this.PhoneNumber = textBoxPhone.Text;
           this.DialogResult = DialogResult.OK;
           this.Close();
       }
    }
    

    然后在你的 FormA 中:

    FormB pad = new FormB();
    var phoneFromFormB = String.Empty;
    if (pad.ShowDialog() == DialogResult.OK)
    {
        phoneFromFormB = pad.PhoneNumber;            
    }    
    

    更新

    如果您需要两个表单都处于活动状态,只需在 FormB 中设置属性而不关闭它。属性设置好后,就可以从FormA访问了。此外,要使它们都处于活动状态,您需要使用 Show() 方法而不是 ShowDialog()

    【讨论】:

      【解决方案4】:

      为什么不将 FormB 创建为表单,而不是将 FormB 创建为 UserControl,它可以添加到 FormA - 在表单设计器中编译后从工具箱中拖动。

      然后,您可以通过 ParentForm 属性或传递给它的引用(具体类或接口)直接从 UserControl 访问 FormA 的属性/方法。短tutorial。这意味着 FormA 和 Dialpad 可以同时处于活动状态,因为 ShowDialog 是模态的。

      也不需要使用 ref 关键字,因为表单是引用类型。注意:我会在 FormA 中实现一个接口并将其用作类型,而不是直接使用 FormA。

      public FormB : UserControl
      {
      
          FormA s = null;
          string txtInput = String.Empty;
      
          public FormB (FormA form1handle)
          {
             InitializeComponent();
              s = form1handle;
          }
      
          public FormB()
          {
      
          }
      
          public FormA Parent 
          { 
              get 
              { 
                  if(s == null)
                     s = (FormA)ParentForm; 
                   return s; 
               } 
           }
      
          public string getFormBValue {
              get { return txtInput; }
          }
      
       private void Dial1_Click(object sender, EventArgs e)
          {
              //txtInput = Dial1.Text;
              Parent.getValue = Dial1.Text;
              MessageBox.Show(Parent.getValue.ToString());           
          }
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-28
        • 2013-05-15
        • 2022-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-22
        相关资源
        最近更新 更多