Forum Xamarin.Forms

Have Bindable Events like Bindable Commands

AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

SUMMARY

(My english is orrible, be patience).
Entry (and I think also other controls) control uses events (TextChanged, Completed) that are not "Bindable" so it's not possible (or... I don't know how) use these in a MVVM situation.
It's possibile to use Behavior but should be useful if XF had is own solution

API Changes

I don't know.
Now there is something like

myControl.SetBinding(Control.CommandProperty,"myCommandProperty");

now should exists also

myEntry.SetBinding(Entry.TextChangedEventProperty, "myTextChangedEventProperty");
myEntry.SetBinding(Entry.CompletedEventProperty, "myCompetedEventProperty");

Intended Use Case

It's permit to use MVVM also with events

Tagged:

Open · Last Updated

Posts

  • WiktorKonckiWiktorKoncki USMember ✭✭

    Not sure how I feel about this. First of all I'm not sure if view model should actually react to interface events. If we look at your first proposed binding then I'm sure this is a totally wrong approach. Your view model should react to changes of underlying properties (in this case String that is bound to entry.text) not to changes of interface state. Changes of interface state are view concern, not view model concern. Second binding makes more sense but it could very well be transformed into a command rather then event.

    All in all I see what you are trying to do but I'm afraid this is actually going against mvvm rather then promote it. I think we could resolve this with adding more commands to controls, like item selection command in list or selection command in picker. Binding events is not the way to go. Events are not view model concern.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    I agree about how having the VM react to UI events is going against all the basic concepts of MVVM design.

    Honestly, a modern developer really shouldn't be working against those old events like TextChanged that are really carry-overs from old WinForms days. They exist to make the transisition easier for people with older skillsets.

    If you adhere to MVVM concepts of reacting to data changes and not UI events you can cover all the same needs in a cleaner way.

    1 example: TextChanged.
    Instead of looking for an event of TextChanged which as you point out is not bindable, you react to the actual text changing in the binded property. You don't care what is happening in the EntryFirstName - you react to the FirstName string property getting updated, by putting your code in the set method of the property.

            #region NameFirst
    
            private string _NameFirst;
    
            public string NameFirst
            {
                [DebuggerStepThrough]
                get
                {
                    //if (_NameFirst == null) _NameFirst = new string();
                    return _NameFirst;
                }
    
                [DebuggerStepThrough]
                set
                {
                    if (_NameFirst == value) return;
                    OnPropertyChanging(() => NameFirst);
                    _NameFirst = value;
                    OnPropertyChanged(() => NameFirst);
                    //Do some other processing here for when this property is changed.
                }
            }
    
            #endregion NameFirst
    
  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    yes @ClintStLaurent .
    Have you a suggestion for "Completed"?
    Thanks

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @AlessandroCaliaro said:
    yes @ClintStLaurent .
    Have you a suggestion for "Completed"?
    Thanks

    Completed is a pure UI event and shouldn't be considered in the VM at all. From a data/logic point of view there is no such thing as Completed. Data is either one thing or another. You have to ask what intended action does Completed actually trigger? What does completing an entry represent in the workflow? Is it validation of the entered text? Is it upload of a file? Is it sending a REST call to a server? All of those actions would be in the VM and not know how or where they get triggered. Uploading a file for example could be triggered from a menu, a gesture, a button tap etc.

    So in the VM you would have the Command and Command Handler for UploadFile because that's pure logic and data.
    In the code behind of the UI you would handle the pure UI event of TextExtryCompleted. In that code behind event handler you could then raise the 'UploadFileCommand`.

    Your xaml and xaml.cs remain strictly about the UI events. The VM remains just about logic and responding to Commands; ignorant of where the commands were raised or how they were executed.

  • AlmaJensen.9398AlmaJensen.9398 USMember ✭✭✭

    I'm using something like this to create new properties that I can bind to that can be triggered by events. But yes I wish there were more Events that had similar properties that could be bound to.

    ` public class BindablePicker : FreshEssentials.BindablePicker
    {
    public static BindableProperty ItemChosenCommandProperty = BindableProperty.Create("ItemChosenProperty", typeof(ICommand), typeof(BindablePicker));
    public BindablePicker()
    {
    this.SelectedIndexChanged += this.OnSelectedIndexChanged;
    }
    public ICommand ItemChosenCommand
    {
    get
    {
    return (ICommand)this.GetValue(ItemChosenCommandProperty);
    }
    set
    {
    this.SetValue(ItemChosenCommandProperty, value);
    }
    }

        private void OnSelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.ItemChosenCommand != null)
                this.ItemChosenCommand.Execute(e);
        }`
    
  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    I'm in favor of having a kind of mechanism for binding to an event, just like it's possible with x:Bind markup extension in WPF.

    The API would be a bit different from what you proposed as it's main usage would be from Xaml

  • AdamPAdamP AUUniversity ✭✭✭✭✭
    edited January 2017

    @AlessandroCaliaro - For the event completed you could use a Trigger, such as:

     <EventTrigger Event="Completed">
    

    I agree with @ClintStLaurent that the Binding shouldn't go directly to the VM. All up, its about the same thing anyway, its just a logical separation, that the UI decides what Command to run, so that the VM doesn't need to know of a View.

    However, I also agree with @StephaneDelcroix. It would be great for XAML, as long as the event handling was bound into the code behind of the View and not the pages BindingContext.

    Retracting that, made little sense now that I think more about it. Still stick by using an event trigger though, hence wondering of any benefit of binding an event to a Command, besides maybe a little less code?

  • ThomasBurkhartThomasBurkhart DEMember ✭✭✭✭

    But why use Binding when we just can assign an event method to the code behind file?
    Also you can always use a EventToCommand behavior if you need to bind this to a ViewModel

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    I might miss something, but I see no point into binding events to the code behind. This scenario is supported since the day one of Xamarin.Forms.

    If there's a Binding, the source of it should be the BindingContext (read: the ViewModel). What I'm unsure of is if should bind to an eventhandler in the BindingContext or to an ICommand. The first one is more discoverable, the second has more value in a MVVM scenario.

  • ChaseFlorellChaseFlorell CAInsider, University mod

    I too might be missing something, but isn't that what a behavior is for though? create a behavior that registers and deregisters an event, and use the respective BindingContext therein.

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    I would agree Behaviors covers this proposed functionality.

    To explain further why I didn't want the Binding to be through to the ViewModel and proposed (but now retracted) code behind, is I wouldn't want to see a ViewModel having UI related handlers.

    Also I may have missed something completely, but I didn't know you could already bind events directly to the code behind, since day one? Or am I just misinterpreting that, and you meant you can handle events in code behind and that there isn't anything like TextChanged="{Binding ...?}" I've been missing all these years.

  • JKayJKay USMember ✭✭✭

    I think youre looking for this https://nuget.org/packages/Corcav.Behaviors/. And a command it contains called EventToCommand.

    The current behavior is exactly the same as WPF so I would stick to how it currently is

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    @AdamP you can do TextChanged="eventHandlerInCodeBehind" since day one. It's no binding, but links to code behind. the missing parts maybe would be the Converter...

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    @AdamP said:
    I would agree Behaviors covers this proposed functionality.

    To explain further why I didn't want the Binding to be through to the ViewModel and proposed (but now retracted) code behind, is I wouldn't want to see a ViewModel having UI related handlers.

    Also I may have missed something completely, but I didn't know you could already bind events directly to the code behind, since day one? Or am I just misinterpreting that, and you meant you can handle events in code behind and that there isn't anything like TextChanged="{Binding ...?}" I've been missing all these years.

    yes Adam, there is nothing like TextChanged = {Binding ...}, or better, there is nothing like Completed = "{Binding ...}"

    I have understand that there are Behaviors, but it's something that I have to add because XF does not "Completed = "{Binding...". If XF could have Binding, I could not use Behaviors...

  • ThomasBurkhartThomasBurkhart DEMember ✭✭✭✭

    Just another thought coming from RxUI. There we have a BindCommand method that accepts an Event Name as additional Argument. Perhaps this would be an approach tat fits Command Binding better. So instead of only being able to bind to Commands defined in a control there could be a generic comand binding with an Event Name as additional parameter

Sign In or Register to comment.