使用通用列表签名进行委托,以便将数据传递给另一个表单
本文关键字:数据 表单 另一个 列表 | 更新日期: 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上,并带有传递数据的委托。因此:
在Form2public 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.
}
// 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
}