使用通用列表签名进行委托,以便将数据传递给另一个表单

本文关键字:数据 表单 另一个 列表 | 更新日期: 2023-09-27 17:55:04

我是c#的新手,所以我在这个问题上挣扎了两天多。我希望有人能帮我解决这个问题。

下面是我的应用程序中的一些简化代码。

我想传递一个列表从Form1到Form2使用委托和事件。

我该怎么做?我读了大量关于事件和委托的解释,但我仍然不明白,这到底是如何工作的。

Form1:

public delegate List<string> ProfileImportEventHandler();
public event ProfileImportEventHandler ProfileImported;
private void btnImport_Click(object sender, EventArgs e)
{
 // raise an event
 OnProfileImported();
}
protected virtual void OnProfileImported()
{
   if (ProfileImported != null) // check if there are subscribers
   {
            ProfileImported();
   }
}

Form2:

public partial class Form2 : Form
{
    Form1 frm1;
    public Form1()
    {
      // Constructor logic
      frm1.ProfileChanged += new Form1.ProfileImportEventHandler(Form1_OnProfileImported);
    }
}
List<string> Form1_OnProfileImported()
{
    // TO DO
}

到目前为止,没有一个解决方案有效。以下是我已经尝试过的:

形式2

    // use generic list for profiles that will be imported from USB-Stick
    private List<string> profilePaths = new List<string>();
    public delegate void ProfileImportEventHandler(object sender, ProfileImportEventArgs e);
    public event ProfileImportEventHandler ProfileImported;
    public delegate void ImportButtonClickedEventHandler();
    public event ImportButtonClickedEventHandler ButtonImportClicked;
    public delegate void HaveDataDelegate(IList<string> data);
    public event HaveDataDelegate HaveData;
//....
    private void btnImport_Click(object sender, EventArgs e)
    {
        // do something... 
        // raise an event
        var ea = new ProfileImportEventArgs(profilePaths);
        OnProfileImported(ea);
        OnButtonImportClicked();
        // When there is data:
        var copy = HaveData; // Use copy to avoid race conditions
        if (copy != null)
        {
            copy(profilePaths);
        }

      // close form
      this.Dispose();        
    }

    protected virtual void OnProfileImported(ProfileImportEventArgs ea)
    {
        if (ProfileImported != null) // check if there are any subscribers
        {
            ProfileImported(this, ea);
        }
    }
    protected virtual void OnButtonImportClicked()
    {
        if (ButtonImportClicked != null)
        {
            // fire event
            ButtonImportClicked();
        }
    }

形式1

public partial class frm_1 : Form
{
// child form
frm_2 frm2;
public frm_1()
    {
        InitializeComponent();
        // do something...
        // not sure if this is correct code and the correct place for it
        frm2 = new frm_2();
        frm2.ProfileImported += new frm_2.ProfileImportEventHandler(frm2_OnProfileImported);
        //frm2.ProfileImported += frm2_OnProfileImported;
        frm2.ButtonImportClicked += new frm_2.ImportButtonClickedEventHandler(frm2_ButtonImportClicked);
        // In creation/init:
        frm2.HaveData += DataFromForm2;
    }
   void frm2_OnProfileImported(object sender, ProfileImportEventArgs e)
    {
        // do something            
    }
    void frm2_ButtonImportClicked()
    {
        // do something             
    }
    private void DataFromForm2(IList<string> data)
    {
        // Process the data from Form2.            
    }

}

我还错过了什么?谢谢你的帮助。

使用通用列表签名进行委托,以便将数据传递给另一个表单

frm1.ProfileChanged += new Form1.ProfileImportEventHandler(Form1_OnProfileImported);

[…]

List<string> frmLoadProfileUSB_OnProfileImported()

首先,这些名称不匹配。其次,有了匹配的签名,你就不需要显式地创建委托了(如果我没记错的话,从c# 2开始)。因此:

frm1.ProfileChanged += frmLoadProfileUSB_OnProfileImported;

然而,我认为你把事件放在了错误的地方。似乎是Form2试图将数据传递给Form1。因此,事件需要在Form2上,并带有传递数据的委托。因此:

在Form2

public delegate void HaveDataDelegate(IList<string> data);
public event HaveDataDelegate HaveData;
// When there is data:
var copy = HaveData; // Use copy to avoid race conditions
if (copy != null) {
  copy(data);
}
在Form1

// In creation/init:
Form2Instance.HaveData += DataFromForm2;

private void DataFromForm2(IList<string> data) {
  // Process the data from Form2.
}

最好不要使用强耦合。因此,最好的解决方案是将数据存储在数据库中或创建代理对象(类/结构)。

:公共(静态)类ProfileChangesMonitor{...你的逻辑是}

如果你想使用事件处理程序,你应该遵循一般的模式,定义一个继承EventArgs的类(假设你想在事件中包含一个列表):

// Event Args
public class ProfileImportEventArgs : EventArgs {
    private IList<string> list;
    public ProfileImportEventArgs(IList<string> list) {
        this.list = list;
    }
    public IList<string> List {
        get {
            return this.list;
        }
   }
}
// Event Handler Delegate
public delegate void ProfileImportEventHandler(object sender, ProfileImportEventArgs e);

// Form1:
public event ProfileImportEventHandler ProfileImported;
// ...    
private void btnImport_Click(object sender, EventArgs e)
{
    // raise an event
    List<string> list = new List();
    // Add something to list if needed
    var ea = new ProfileImportEventArgs(list);
    OnProfileImported(ea);
    // Use ea.list here if necessary
}
protected virtual void OnProfileImported(ProfileImportEventArgs ea)
{
   if (ProfileImported != null) { // check if there are subscribers
        ProfileImported(this, ea);
   }
}
// Form2:
public partial class Form2 : Form
{
    Form1 frm1;
    public Form1()
    {
      // Constructor logic
      // TODO: Instantiate frm1 first.
      frm1.ProfileImported += new Form1.ProfileImportEventHandler(Form1_OnProfileImported);
    }
}
private void frmLoadProfileUSB_OnProfileImported(object sender, ProfileImportEventArgs e)
{
    // Use and/or modify e.List if needed         
}