使用通用列表签名委派将数据传递到另一个表单

时间:2015-06-10 13:19:48

标签: c# winforms events delegates

我是C#的新手,所以我在这两天以上都在挣扎。我希望有人可以帮助我解决这个问题。

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

我想使用委托和事件将List从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();
   }
}

窗体2:

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.            
    }


}

我还缺少什么?谢谢您的帮助。

3 个答案:

答案 0 :(得分:1)

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.
}

答案 1 :(得分:0)

如果你想使用事件处理程序,你应该遵循一般模式,定义一个继承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         
}

答案 2 :(得分:0)

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

像: public(静态)类ProfileChangesMonitor {    ......你的逻辑在这里 }