如何从事件中删除/取消注册事件处理程序?

时间:2011-09-15 12:00:51

标签: c# events uitableview mono xamarin.ios

我做了一个自定义的uitableviewcell。单元格由标签和UIButton组成。一切都工作正常,直到我发现可重复使用的细胞与向uibutton添加事件相结合存在一个小问题。 所以当我点击uibutton时,单元格第一次工作得很好。但是当我滚动它的那一刻开始给我错误的细节信息。如果我注释掉可重复使用的单元格部分(并且每次都让它创建一个新的单元格),它就可以正常工作而没有任何问题。所以我的假设是事件'挂起'进入具有旧信息的单元格。 我添加这样的事件:

myButton.TouchDown += delegate{
  //some code here
}

显然我不能像这样取消注册吗? 在monotouch中克服这个特殊问题的最简单方法是什么?

4 个答案:

答案 0 :(得分:9)

您可以将匿名方法和lambda作为事件处理程序。只需将它们保存为局部变量即可。

EventHandler theHandler = delegate(obj sender, EventArgs e) 
{ Console.WriteLine("The handler!"); };
//... or: EventHandler theHandler = (sender, args) => { Console.WriteLine("The handler!"); };
private void HookEvent()
{
    myButton.TouchDown += this.theHandler;
}

private void UnhookEvent()
{
    myButton.TouchDown -= this.theHandler;
}

答案 1 :(得分:3)

如果您希望能够取消注册事件处理程序,则不应使用匿名方法(或lambdas)。将您的代码移动到实际方法中并将其注册为:

private void MyMethod()
{
  //some code here
}

// register
myButton.TouchDown += MyMethod;

// unregister
myButton.TouchDown -= MyMethod;

答案 2 :(得分:3)

行。我一直在尝试很多东西来解决这个问题,但ChrisNTR为我的特定问题提供了正确的解决方案。我将在这里展示他的示例片段:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell("reuseThis");
if(cell == null)
{
cell = new UITableViewCell(UITableViewCellStyle.Default, "reuseThis");
}

cell.TextLabel.Text = Convert.ToChar(dash.oneToHundred[indexPath.Row]).ToString();

var button = UIButton.FromType(UIButtonType.RoundedRect);
button.Frame = new System.Drawing.RectangleF(40f, 0f, 280f, 40f);
button.SetTitle(dash.oneToHundred[indexPath.Row].ToString(),UIControlState.Normal);
button.AddTarget (this, new Selector ("MySelector"), UIControlEvent.TouchDown);
button.Tag = indexPath.Row;
cell.ContentView.AddSubview(button);

return cell;
}

[Export ("MySelector")]
void ButtonEventHere (UIButton button)
{

Console.WriteLine ("Hello! - Button clicked = " + button.Tag );
Console.WriteLine ( Convert.ToChar(dash.oneToHundred[button.Tag]).ToString() );
}

简而言之,您调用button.AddTarget()并将相应的值传递给按钮。其中一个值是您定义为'buttonEventHere'的选择器(可以是您想要的任何名称,我确定[export(“MySelector”)]具有正确的名称)。确保将indexPath.Row传递给button.Tag。您将使用该索引来了解按下了哪个按钮并相应地执行操作。

希望如果你像我一样被困住,这会有所帮助。

答案 3 :(得分:0)

您可能希望使用此技术来确定按下哪个UIButton而不是尝试使用会出现问题的自定义事件参数 - http://jainmarket.blogspot.com/2009/05/custom-button-in-uitableviewcell.html

基本上,您只需确定在UITableViewCell中选择的部分/行。从那里你应该能够找出UIButton的选择。

希望这有帮助,

ChrisNTR