Как я могу привязать событие подпредставления UITableViewCell к модели представления ICommand?

У меня есть представление, которое использует несколько элементов MonoTouch.Dialog для управления экраном. Мне удалось создать плавные привязки для всех элементов управления экраном, кроме одного, ButtonElement, потому что я не могу получить доступ к событию TouchUpInside его подпредставления UIButton.

Вот псевдокод, который создает элементы управления, строит экран и создает привязки.

// Controls created
CheckboxElement checkbox = new CheckboxElement("Lorem ipsum dolor");
StringElement string1 = new StringElement("Sit amet");
StringElement string2 = new StringElement("Consectetur");
ButtonElement button = new ButtonElement("Adipiscing", delegate{method();});

// Elements used to create view
List<Element> elements = new List<Element>(){checkbox, string1, string2, button};
AddElements(elements);

// Bind controls to view model properties
var set = this.CreateBindingSet<SettingsView, SettingsViewModel>();

set.Bind(checkbox).For(v => v.BooleanValue).To(vm => vm.CheckboxProperty).TwoWay();
set.Bind(string1).For(v => v.Value).To(vm => vm.String1Property);
set.Bind(string2).For(v => v.Value).To(vm => vm.String2Property);
// Binding to ButtonElement TouchUpInside event would go here

set.Apply();

ButtonElement, который имеет UIButton в качестве единственного подпредставления, и это событие TouchUpInside этого подпредставления, которое я хочу связать с методом ICommand в модели представления.

public ICommand TouchUpInsideCommand()
{
    get { ... }
}

Прямо сейчас в ButtonElement, когда UIButton создается в GetCell, его событие TouchUpInside связано с анонимным методом делегата, который передается как часть конструктора ButtonElement и сохраняется в NSAction с именем Tapped.

button.TouchUpInside += (o, e) => Tapped.Invoke();

Чтобы удалить эту обработку событий, я создал новый класс с именем ButtonElementMvx, который наследуется от ButtonElement. В методе GetCell ButtonElementMvx я удаляю обработку событий, которая была настроена его родителем.

public ButtonElementMvx : ButtonElement
{
    ...

    public override UITableViewCell GetCell(UITableView tv)
    {
        UITableViewCell cell = base.GetCell(tv);
        button.TouchUpInside -= ButtonTouchUpInsideEventHandler;
        return cell;
    }
}

ButtonTouchUpInsideEventHandler — это ссылка на анонимный метод делегата, созданный в GetCell ButtonElement (я знаю, что эта реализация может быть немного неуклюжей, но я исправлю ее позже).

Вот мой вопрос: как лучше всего создать привязку к событию ButtonElement UIButton TouchUpInside внутри моего представления, где я создаю другие привязки?

buttonElement : ButtonElement
    |
    -> uiButton : UIButton
        |
        -> TouchUpInside

Что-то в духе

set.Bind(buttonElement.uiButton).For("TouchUpInside").To(vm => vm.TouchUpInsideCommand);

Я провел некоторое исследование и думаю, что путь вперед заключается в создании пользовательской привязки, которая добавляется в реестр при запуске (описано в статье Стюарта N=28 — Custom Binding видео), а также расширение моего класса ButtonElementMvx до создать полностью привязываемый UIButton, чтобы я мог получить доступ к событию TouchUpInside кнопки и привязать его в моем вид вместе с другими моими элементами управления.

есть идеи? Это правильный способ продолжить или я направляюсь в неправильном направлении?


person billmaya    schedule 29.01.2014    source источник
comment
Можете выложить весь ButtonElement или ссылку на него? А также вы используете копию диалогового окна Mvx или оригинал Xamarin?   -  person Stuart    schedule 30.01.2014
comment
@Stuart - я использую исходную среду Xamarin Dialog/Element с модификациями. Исходный код ButtonElement.cs можно найти по этой общедоступной ссылке Dropbox — dl.dropboxusercontent.com/ u/9555786/ButtonCode.cs (я оставлю его активным на день или два)   -  person billmaya    schedule 30.01.2014
comment
@Stuart — файл ButtonCode.cs содержит классы ButtonElement и ButtonElementMvx.   -  person billmaya    schedule 30.01.2014