我们一直在使用像这样的lamda事件:
bookMarkClient.wmdeleteCompleted += (s, ea) =>
{
if (ea.Result = "Success")
{
foreach (BookMark bookMark in BookMarks)
{
if (bookMarkId == bookMark.bm_id)
{
BookMarks.Remove(bookMark);
OnNotifyPropertyChanged("BookMarks");
break;
}
}
}
};
bookMarkClient.wmdeleteBookMarkAsync(bookMarkId);
但是根据stackoverflow上的许多答案,这些都无法删除,这样如果我再次调用此代码,我的事件将被触发两次。所以我想删除lambda代码并执行此操作:
//in the class constructor
bookMarkClient.wmdeleteBookMarkCompleted += new EventHandler<wmdeleteBookMarkCompletedEventArgs>(bookMarkClient_wmdeleteBookMarkCompleted);
//Proc on the same class
void bookMarkClient_wmdeleteBookMarkCompleted(object sender, wmdeleteBookMarkCompletedEventArgs e)
{
if (ea.Result = "Success")
{
foreach (BookMark bookMark in BookMarks)
{
if (bookMarkId == bookMark.bm_id)
{
BookMarks.Remove(bookMark);
OnNotifyPropertyChanged("BookMarks");
break;
}
}
}
}
//on button click
bookMarkClient.wmdeleteBookMarkAsync(bookMarkId);
但是:变量bookMarkId不再可用。我理解这是因为lambda事件将变量复制到构造的类中,并在事件持续时间内保持活动状态。 那我该如何做呢?
我已尝试设置私有变量,但测试显示可以在收到回拨之前更改它!这也适用于名为Bookmarks的集合。
注意,这是一个Silverlight客户端,我宁愿不传回事件args中的Id /集合,因为这意味着要重新编写大量的wcf代码。
非常感谢,马特
ps首先发布到堆栈,所以请放轻松...
答案 0 :(得分:2)
将事件处理程序存储在本地变量中;然后你可以添加和删除相同的事件处理程序:
EventHandler<wmdeleteBookMarkCompletedEventArgs> handler = (s, ea) => { .... }
bookMarkClient.wmdeleteBookMarkCompleted += handler;
// ...
bookMarkClient.wmdeleteBookMarkCompleted -= handler;
或者,lambda表达式只是编译器生成的嵌套类的语法糖。如果您无法将书签ID添加到EventArgs,请通过创建自己的类来模拟lambda:
BookmarkDeletedListener listener = new BookmarkDeletedListener(this, bookMarkId);
bookMarkClient.wmdeleteBookMarkCompleted += listener.DeleteBookmarkCompleted;
bookMarkClient.wmdeleteBookMarkCompleted -= listener.DeleteBookmarkCompleted;
// ...
class BookmarkDeletedListener
{
public BookmarkDeletedListener(ParentClass parent, string bookmarkId)
{
_parent = parent;
_bookmarkId = bookmarkId;
}
public DeleteBookmarkCompleted(object sender, wmdeleteBookMarkCompletedEventArgs e)
{
if (ea.Result = "Success")
{
foreach (BookMark bookMark in BookMarks)
{
if (_bookmarkId == bookMark.bm_id)
{
_parent.BookMarks.Remove(bookMark);
_parent.OnNotifyPropertyChanged("BookMarks");
break;
}
}
}
}
readonly ParentClass _parent;
readonly string _bookmarkId;
}
答案 1 :(得分:0)
你可以删除lambda,AFAIK,只要你抓住它。它甚至可以在被解雇时自行移除:
Action<object, wmdeleteBookMarkCompletedEventArgs> handler;
handler =
(s, ea) =>
{
bookMarkClient.wmdeleteCompleted -= handler;
if (ea.Result == "Success")
...
};
bookMarkClient.wmdeleteCompleted += handler;