两种表单C#之间的通信

时间:2019-04-18 16:29:15

标签: c# winforms

我有三种形式,主要形式是Form2,而Form2具有Form3作为构造函数,并且与Form3(Form2的构造函数)相同。

实际上,我正在尝试将Form3的信息放入Form2中。

我有一个带有信息(Form2)的DataGridView,我想在文本框中的Form3的开头放置信息。

我可以做到这一点,但我也想通过关闭Form3后打开向Form2发送信息的Form3,以在DataGridView(Form2)中创建新行。

在我的主要表单中:

        private void btn_gestCapteur_Click(object sender, EventArgs e)
        {
            FormGestionCapteurs fGesCapt;
            fGesCapt = new FormGestionCapteurs();

            FormGestionCapteurs fGestCapt;
            fGestCapt = new FormGestionCapteurs(fConfRes, new FormAjoutCapteur(fConfRes,fGesCapt));
            fGestCapt.ShowDialog();
        }

在我的Form1中,它称为FormGestionCapteurs:

        FormAjoutCapteur fAddCpt;

        FormConfigReseau fConfRes;

        public FormGestionCapteurs(FormConfigReseau fConfRes, FormAjoutCapteur fAddCpt)
        {
            InitializeComponent();

            this.fConfRes = fConfRes;

            this.fAddCpt = fAddCpt;
        }

        public FormGestionCapteurs()
        {
            InitializeComponent();
        }

在我的Form3中,它称为FormAjoutCapteurs:

        FormGestionCapteurs fGest;

        FormConfigReseau fConfRes;

        public FormAjoutCapteur(FormConfigReseau fConfRes, FormGestionCapteurs fGest)
        {
            InitializeComponent();

            this.fConfRes = fConfRes;

            this.fGest = fGest;
        }

        private void btn_ok_Click(object sender, EventArgs e)
        {
         DataGridViewRow row = (DataGridViewRow)fGest.tab_listeCapteurs.Rows[0].Clone(); //fGest. is the Form2 and tab_listeCapteurs is the DataGridView
                    row.Cells[0].Value = txtBox_name.Text; //These textboxes aren't empty so I want to send the text of these in the good cells of my DataGridView
                    row.Cells[1].Value = txtBox_marque.Text;
                    row.Cells[2].Value = txtBox_model.Text;
                    row.Cells[3].Value = numUpDown_calibre.Value;
                    row.Cells[4].Value = txtBox_a.Text;
                    row.Cells[5].Value = txtBox_b.Text;
                    fGest.tab_listeCapteurs.Rows.Add(row);
                    //This code doesn't effect
        }

我可以在Form3上发送DataGridView的信息,但是当我想在关闭Form3后在Form2中创建新行时,不会插入该行。

3 个答案:

答案 0 :(得分:0)

您可以通过使用委托来做到这一点。我几乎无法理解您的问题,但是我相信这会有所帮助。 只需根据需要修改代码即可。

public partial class Form3 : Form
{
    public delegate void callback_data(string dataToSend);
    public event callback_data sentIt;


   private void form3_FormClosing(object sender, FormClosingEventArgs e)
   {
       string data = "Top Secret Data";
       sentIt(data);
   }
}

现在在要创建Form3实例的Form2中调用事件。

public partial class Form2 : Form
{

   private void Form2_OnLoad()
   {
       Form2 obj = new Form2();
       obj.sentIt += onReceiveData;
       obj.ShowDialog();
   }

   private void onReceiveData(string myData)
   {
      console.WriteLine(myData);
   }
}

通过这种方式,您将数据从Form3获取到Form2 .. 我已经尝试了200种新技术:p,但这代表是这样做的最有效方法!相信我。

答案 1 :(得分:0)

一个快速的答案,请参见代码中的注释。但看起来“ Form1”对您的问题没有帮助。

public partial class Form2 : Form
{
    //No need to use constructor, this is good for a frequently open/close child form.
    private readonly FormAjoutCapteur formAjoutCapteur = new FormAjoutCapteur();

    public Form2()
    {
        InitializeComponent();

        formAjoutCapteur.FormClosed += FormAjoutCapteur_FormClosed; //this is simplest way to get inputs
        //formAjoutCapteur.BtnOK.Click += FormAjoutCapteur_BtnOK_Click; //this require the button's "Modifiers" must be "Public"
    }

    private void FormAjoutCapteur_FormClosed(object sender, FormClosedEventArgs e)
    {
        var text = formAjoutCapteur.textBoxInput.Text;//you can simply change the input "modifiers" as "public"
        //var obj = formAjoutCapteur.GetInputs(); // you can make a public method to return all input into an object, which is recommended.

        //add your row
        this.dataGridView1.Rows.Add(new DataGridViewRow());
    }

    private void BtnGestionCapteurs_Click(object sender, EventArgs e)
    {
        formAjoutCapteur.ShowDialog(this);
    }
}

答案 2 :(得分:0)

我认为您所掌握的是主/从形式的情况。 .NET Framework具有许多内置功能来处理此类问题。我真的不了解请求的详细信息,因此这可能会对您有所帮助。我还建议您读一本书或参加有关数据绑定的课程,因为这将比手动更新文本框和手动移动数据容易得多。

A部分-主视图

首先创建一个数据模型来表示数据网格中的每一行。从发布中,我假设使用以下数据模型:

/// <summary>
/// Defines a Capteurs
/// </summary>
public class Capteurs : ICloneable
{
    public Capteurs()
    {
        this.Name=  string.Empty;
        this.Marque=  string.Empty;
        this.Model=  string.Empty;
        this.Calibre=  0;
        this.A=  string.Empty;
        this.B=  string.Empty;
    }
    public Capteurs(Capteurs other)
    {
        this.Name = other.Name;
        this.Marque = other.Marque;
        this.Model = other.Model;
        this.Calibre= other.Calibre;
        this.A=other.A;
        this.B=other.B; 
    }

    public string Name { get; set; }
    public string Marque { get; set; }
    public string Model { get; set; }
    public int Calibre { get; set; }
    public string A { get; set; }
    public string B { get; set; }

    #region ICloneable Members
    public Capteurs Clone() => new Capteurs(this);
    object ICloneable.Clone() => Clone();
    #endregion

}

Noticed我实现了ICloneable以便复制数据,因此除非希望,否则我不会打扰主列表。

接下来,我基于此类在项目中添加了数据源

add data source

主表单包含一个DataGridView,以显示链接到数据源的所有数据

data link

现在,在加载表单时,我使用capteursBindingSource.DataSource = list;将数据添加到数据源,并且项目列表显示在主表单上。

master form

将以下属性添加到主表单中,以便可以访问当前选定的项目,列表管理器,项目列表和当前项目的索引。

public Capteurs Current
{
    get => List[Index];
    set => List[Index] = value;
}
public CurrencyManager CurrencyManager 
{ 
    get => BindingContext[capteursBindingSource] as CurrencyManager; 
}
public IList<Capteurs> List 
{ 
    get => capteursBindingSource.DataSource as IList<Capteurs>; 
}
public int Index
{
    get => BindingContext[capteursBindingSource].Position;
    set => BindingContext[capteursBindingSource].Position = value;
}

B部分-详细视图

创建第二个表单并将数据源拖到表单表面

data as details

drag and drop

删除定位工具栏(因为一次仅显示一组数据)。组织创建的控件,并添加“确定” /“取消”或“接受/关闭”等按钮,以表明所做的编辑是否正确。

detail form

最后,添加以下属性以获取或设置要以

形式显示的数据
public Capteurs Current
{
    get => BindingContext[capteursBindingSource].Current as Capteurs;
    set => capteursBindingSource.DataSource = new Capteurs[] { value };
}

C部分-链接表单

完成上述所有操作是为了简化表单之间的数据传输。在主表单中,以下按钮处理程序打开详细信息表单,发送当前数据的副本,如果用户选择[保留],则将已编辑的数据存储回主列表中,并刷新网格使用CurrencyManager.Refresh()命令。

private void detailsButton_Click(object sender, EventArgs e)
{
    var dlg = new DetaillForm();
    dlg.Current = this.Current.Clone();

    if (dlg.ShowDialog(this) == DialogResult.OK)
    {
        this.Current = dlg.Current;
        CurrencyManager.Refresh();
    }
}

the final result