Как мне удалить / отменить регистрацию события из события? - PullRequest
3 голосов
/ 15 сентября 2011

Я сделал пользовательскую ячейку просмотра. Ячейка состоит из меток и кнопки UIB. Все работало нормально, пока я не обнаружил, что есть небольшая проблема с ячейкой многократного использования в сочетании с добавлением события в uibutton. Так что в первый раз, когда я нажимаю на uibutton, ячейка работает отлично. Но в тот момент, когда я прокручиваю, он начинает давать мне неправильную подробную информацию. Если я закомментирую многократно используемую часть ячейки (и позволю ей каждый раз создавать новую ячейку), она просто работает без проблем. Поэтому я предполагаю, что событие «висит» в ячейке со старой информацией. Я добавляю событие так:

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

Очевидно, я не могу отменить регистрацию, как это верно? Какой самый простой способ преодолеть эту проблему в Monotouch?

Ответы [ 4 ]

9 голосов
/ 15 сентября 2011

Вы можете иметь анонимные методы и лямбды в качестве обработчиков событий. Просто сохраните их как локальные переменные.

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;
}
3 голосов
/ 26 сентября 2011

OK. Я много чего пытался решить, но 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 голосов
/ 15 сентября 2011

Если вы хотите иметь возможность отменить регистрацию вашего обработчика событий, вы не должны использовать анонимные методы (или лямбды). Переместите свой код в реальный метод и зарегистрируйте его следующим образом:

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

// register
myButton.TouchDown += MyMethod;

// unregister
myButton.TouchDown -= MyMethod;
0 голосов
/ 19 сентября 2011

Возможно, вы захотите использовать эту технику, чтобы выяснить, какая кнопка UIButton была нажата, а не пытаться использовать пользовательские аргументы событий, что будет проблематично - http://jainmarket.blogspot.com/2009/05/custom-button-in-uitableviewcell.html

По сути, вы просто решаете, какой раздел / строка был выбран в UITableViewCell. Оттуда вы сможете понять, какой UIButton был выбран.

Надеюсь, это поможет,

ChrisNTR

...