0

I have a view that uses several MonoTouch.Dialog elements for screen controls. I've been able to create fluent bindings for all of the screen controls except one, a ButtonElement, because I can't access the TouchUpInside event of its UIButton subview.

Here's the pseudocode that creates the controls, builds the screen, and creates the bindings.

// 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();

The ButtonElement that has a UIButton as its only subview and it is this subview's TouchUpInside event that I want to link to an ICommand method in the view model.

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

Right now in ButtonElement, when the UIButton is created in GetCell, its TouchUpInside event is linked to the anonymous delegate method that's passed in as part of ButtonElement's constructor and stored in an NSAction called Tapped.

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

To remove this event handling I've created a new class called ButtonElementMvx that inherits from ButtonElement. In ButtonElementMvx's GetCell method I remove the event handling that was set up by its parent .

public ButtonElementMvx : ButtonElement
{
    ...

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

ButtonTouchUpInsideEventHandler is a reference to the anonymous delegate method created in ButtonElement's GetCell (I know this implementation might be a bit kludgy but I'll clean it up later).

Here's my question - What is the best way to create a binding to the ButtonElement's UIButton TouchUpInside event inside my view where I'm creating my other bindings?

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

Something along the lines of

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

I've done some research and I think the way forward is to create a custom binding that is added to the registry on startup (outlined in Stuart's N=28 - Custom Binding video) as well as extending my ButtonElementMvx class to create a fully bindable UIButton that I can access the button's TouchUpInside event and bind it in my view along with my other controls.

Any thoughts? Is this the correct way to proceed or am I heading off in the wrong direction?

Community
  • 1
  • 1
billmaya
  • 1,311
  • 3
  • 15
  • 34
  • Can you post the whole `ButtonElement` or a link to it? And also are you using Mvx's copy of Dialog or the Xamarin original? – Stuart Jan 29 '14 at 20:56
  • @Stuart - I'm using the original Xamarin Dialog/Element framework with modifications. The ButtonElement.cs source can be found at this public Dropbox link - https://dl.dropboxusercontent.com/u/9555786/ButtonCode.cs (I'll keep it active for a day or two) – billmaya Jan 29 '14 at 21:35
  • @Stuart - the ButtonCode.cs file contains both the ButtonElement and ButtonElementMvx classes. – billmaya Jan 29 '14 at 22:58

0 Answers0