我正在努力解决事件。我有一个用户控件,我想从用户双击时返回ID字段。这是我的用户控件代码:
// inside the user control class:
public event EventHandler<SelectedItemEventArgs> ItemHasBeenSelected;
public class SelectedItemEventArgs : EventArgs
{
public int SelectedChoice { get; set; }
}
private void DataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
var handler = ItemHasBeenSelected;
if (e.RowIndex >= 0 && e.RowIndex < DataGridView.RowCount)
{
// 6 == id column
int choice = (int)DataGridView[6, First ? 0 : e.RowIndex].Value;
if (handler != null)
handler(this, new SelectedItemEventArgs { SelectedChoice = hoice });
}
}
在调用程序中:
public Main
{
InitializeComponent();
uc.ItemHasBeenSelected += uc_ItemHasBeenSelected;
}
private void uc_ItemHasBeenSelected(object sender, FindControl.SelectedItemEventArgs e)
{
var value = e.SelectedChoice;
currentVal = value;
}
我一直得到我的事件处理程序(var handler)= null。我知道我必须遗漏一些东西,但它已经过了很多个小时而我却无法找到它。如果可以,请帮忙。
答案 0 :(得分:1)
根据尼克回答的评论,Missy要求我发布举办活动的最佳做法。
我简化了您的代码来说明:
public event EventHandler<SelectedItemEventArgs> ItemHasBeenSelected;
public class SelectedItemEventArgs : EventArgs { }
private void OnItemHasBeenSelected()
{
var handler = this.ItemHasBeenSelected;
if (handler != null)
{
handler(this, new SelectedItemEventArgs());
}
}
这里要注意的关键是作业var handler = this.ItemHasBeenSelected;
。这会生成委托的副本,因此会附加处理程序,这意味着如果this.ItemHasBeenSelected
发生任何事情,则不会影响handler
。
与以下内容比较:
private void OnItemHasBeenSelected()
{
if (this.ItemHasBeenSelected != null)
{
this.ItemHasBeenSelected(this, new SelectedItemEventArgs());
}
}
在这种情况下,在检查this.ItemHasBeenSelected != null
之后但在调用this.ItemHasBeenSelected(this, new SelectedItemEventArgs());
之前有一个错误,另一个线程(或者在更复杂的情况下甚至是异步代码)可以删除处理程序,以便后续调用将失败,因为委托现在将为null
。
使用var handler = this.ItemHasBeenSelected;
分配可以避免这种情况。
答案 1 :(得分:0)
首先,创建一个事件委托:
public delegate void ItemHasBeenSelected (object sender, SelectedItemEventArgs e);
实例化事件委托:
public event ItemHasBeenSelected SelectedItem;
如果您想举起活动:
this.SelectedItem(this, new SelectedItemEventArgs { SelectedChoice = choice })
完成此设置后,您可以将事件绑定到事件处理程序:
this.SelectedItem += main.uc_ItemHasBeenSelected;
如果要在表单中定义委托,而不是您希望事件处理程序的位置,则需要将this
值传递到表单的构造函数中并将其存储在表格中的变量。在分配事件处理程序时引用该变量。
或
从控件中定义委托,并在为事件分配处理程序时从主程序中引用委托。
Control.SelectedItem += this.uc_ItemHasBeenSelected;