[英]How do I unsubscribe from a lambda event that needs variables passing into it?
I have a custom control in WPF (MenuButton) and want to add a click event handler to a list of them.我在 WPF (MenuButton) 中有一个自定义控件,并希望将单击事件处理程序添加到它们的列表中。 The event handler requires an integer to be passed into it, like so:事件处理程序需要将 integer 传递给它,如下所示:
List<MenuButton> mbButtons;
private void SetUpButtons()
{
Random r = new Random();
foreach (MenuButton item in mbButtons)
{
SubscribeToClickEvent(item, r.Next(0, 11));
}
}
private void SubscribeToClickEvent(MenuButton mb, int i)
{
mb.Click += (sender, e) => MyClickEvent(sender, e, i);
}
But how do I then unsubscribe from the event for each button?但是我如何取消订阅每个按钮的事件呢?
You need to store the delegate, and use it again to unsubscribe.您需要存储委托,并再次使用它来取消订阅。
private RoutedEventHandler handler;
private void SubscribeToClickEvent(MenuButton mb, int i)
{
handler = (sender, e) => MyClickEvent(sender, e, i);
mb.Click += handler;
}
private void UnsubscribeFromClickEvent(MenuButton mb)
{
mb.Click -= handler;
handler = null;
}
Of course, add your own logic to handle the case where SubscribeToClickEvent
is called more than once.当然,添加您自己的逻辑来处理多次调用SubscribeToClickEvent
的情况。
You edited your question to have an array of buttons, so here's an adjusted answer:您将问题编辑为具有一系列按钮,因此这是一个调整后的答案:
You will need to keep a list of delegate instances to remove:您需要保留要删除的委托实例列表:
private List<MenuButton> mbButtons;
private readonly List<(MenuButton button, RoutedEventHandler handler)> clickHandlers = new List<(MenuButton, RoutedEventHandler)>();
private void SetUpButtons()
{
Random r = new Random();
foreach (MenuButton item in mbButtons)
{
SubscribeToClickEvent(item, r.Next(0, 11));
}
}
private void SubscribeToClickEvent(MenuButton mb, int i)
{
RoutedEventHandler handler = (sender, e) => MyClickEvent(sender, e, i);
clickHandlers.Add((mb, handler));
mb.Click += handler;
}
private void UnsubscribeFromClickEvents()
{
foreach (var (button, handler) in clickHandlers)
{
button.Click -= handler;
}
clickHandlers.Clear();
}
it makes more sense to keep relevant data in button instance, and retrive it in event handler:将相关数据保存在按钮实例中并在事件处理程序中检索它更有意义:
List<MenuButton> mbButtons;
private void SetUpButtons()
{
Random r = new Random();
foreach (MenuButton item in mbButtons)
{
item.Tag = r.Next(0, 11);
item.Click += MyClickEvent;
}
}
private void MyClickEvent(object sender, RoutedEventArgs e)
{
var mb = (MenuButton)sender;
int i = (int)mb.Tag;
}
then unsubscribe without any difficulties using known method name:然后使用已知方法名称毫无困难地取消订阅:
mb.Click -= MyClickEvent;
It's been a while since I worked with WPF but I'm pretty sure you can just have another method that does the opposite:自从我使用 WPF 以来已经有一段时间了,但我很确定您可以使用另一种相反的方法:
private void UnsubscribeToClickEvent(MenuButton mb, int i)
{
mb.Click -= (sender, e) => MyClickEvent(sender, e, i);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.