How to determine when Editor text has changed in viewModel

ChrisVardonChrisVardon GBMember ✭✭

I have an editor in which I am currently saving to the device, but I also want to know when the text has changed so I will know if I need to bother saving the text (only needs to be saved if different to before). I know the editor has a text changed event, but is there a way I can use this without writing code in the view codebehind, so that I can perform a check in the viewModel?

Answers

  • voidstreamvoidstream FRMember ✭✭✭

    Behaviours is the best way here?
    The text of editor can be bind in viewmodels and in the set of the properties you can determine the editing?

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    You should be able to bind to TextChanged event

  • NMackayNMackay GBInsider, University mod

    +1 for david's behavior library.

    You can also listen for property changes and trigger commands/actions etc. I use this approach to set custom pins in a map when the mapping data comes back from the service.

    <ContentView.Behaviors>
          <b:DataChangedBehavior Binding="{Binding GeoPos}" ComparisonCondition="NotEqual" Value="{x:Null}">
            <b:InvokeMethodAction TargetObject="{Binding Source={x:Reference MapView}}"
                                  MethodName="MapRefresh" />
          </b:DataChangedBehavior>
        </ContentView.Behaviors>
    
  • ChrisVardonChrisVardon GBMember ✭✭

    So would the comparison be made between the old and new text value in the behaviour or in the view model? @AlessandroCaliaro @NMackay

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    For example, in my Page (I don't use XAML), I have

    InvokeCommandAction icaOnAppearing = new InvokeCommandAction();
    icaOnAppearing.SetBinding(InvokeCommandAction.CommandProperty, "OnAppearingCommand");
    EventHandlerBehavior ehbOnAppearing = new EventHandlerBehavior() { EventName = "Appearing" };
    ehbOnAppearing.Actions.Add(icaOnAppearing);
    
    this.Behaviors.Add(ehbOnAppearing);
    

    What does it mean? In MV I have a OnAppearingCommand, I Attach this Command to "Appearing" (OnAppearing) Page's event, and Add the Behavior to "this.Behaviors".

    I think you can do the same with TextChanged event. Something like

    InvokeCommandAction icaTextChanged = new InvokeCommandAction();
    icaTextChanged.SetBinding(InvokeCommandAction.CommandProperty, "TextChangedCommand");
    EventHandlerBehavior ehbTextChanged = new EventHandlerBehavior() { EventName = "TextChanged" };
    ehbTextChanged.Actions.Add(icaTextChanged);
    
    myEditor.Behaviors.Add(ehbTextChanged);
    

    (not tested...)

  • NMackayNMackay GBInsider, University mod

    In XAML....

    <Entry x:Name="EntryUid" Text="{Binding Uid, Mode=TwoWay}" Placeholder="Username" VerticalOptions="Fill" HorizontalOptions="FillAndExpand"> <Entry.Behaviors> <b:EventHandlerBehavior EventName="TextChanged"> <b:InvokeCommandAction Command="{Binding TextChangedCommand}" /> </b:EventHandlerBehavior> </Entry.Behaviors> </Entry>

  • ledragonledragon Member ✭✭
    edited July 29

    Hi Guys,

    Old question I know but do you know of anyway to create a composite event? By this I mean have an Prism EventToCommandBehavior for unfocused event and DataChangedBehavior for if the value of the entry control changes and only call a Viewmodel Command if both are true?

    Reason for this is I'm finding on a certain device I'm testing on with an entry in a listview, the unfocused event is firing repeatedly and unexpectedly even when the entry is in focus. It seems to be when the keyboard is active but I've not 100% narrowed the cause yet. I've only tested on 2 devices so far (Android 6 and 8) and it's v6 where this happens...the v6 device also has a small screen so I'm wondering if the keyboard pushing the entry around when it loads on a small screen causes it to lose focus.

    Thanks in advance

  • NMackayNMackay GBInsider, University mod

    @ledragon said:
    Hi Guys,

    Old question I know but do you know of anyway to create a composite event? By this I mean have an Prism EventToCommandBehavior for unfocused event and DataChangedBehavior for if the value of the entry control changes and only call a Viewmodel Command if both are true?

    Reason for this is I'm finding on a certain device I'm testing on with an entry in a listview, the unfocused event is firing repeatedly and unexpectedly even when the entry is in focus. It seems to be when the keyboard is active but I've not 100% narrowed the cause yet. I've only tested on 2 devices so far (Android 6 and 8) and it's v6 where this happens...the v6 device also has a small screen so I'm wondering if the keyboard pushing the entry around when it loads on a small screen causes it to lose focus.

    Thanks in advance

    That sounds very messy. You might be better creating a composite control (ContentView) with the Entry and add some attached bindings such as TextValue and ValidEntryCommand, handle the checks in the composite control and only fire the command when your conditions are satisfied.

    Also watch entries in a Listview Android in Marshmallow, if they have focus and you rotate the device...dark stuff can happen...certain in Forms 3.4 (it's an easy renderer fix) on devices with Touchwiz (S5 etc)

  • ledragonledragon Member ✭✭
    edited July 29

    @NMackay said:
    That sounds very messy. You might be better creating a composite control (ContentView) with the Entry and add some attached bindings such as TextValue and ValidEntryCommand, handle the checks in the composite control and only fire the command when your conditions are satisfied.

    Also watch entries in a Listview Android in Marshmallow, if they have focus and you rotate the device...dark stuff can happen...certain in Forms 3.4 (it's an easy renderer fix) on devices with Touchwiz (S5 etc)

    Thanks for the reply.

    I'll have a look into a composite control. Do you know of a good link I can use for reference? ;-) I'm on forms v3.6 but it could be related. Actually the Android v8 device I don't see the issue on is an s8. The v6 is a Motorola Moto E.

    I was tempted by this:

    http://prismlibrary.github.io/docs/composite-commands.html

    Would you recommend me away from this then?

  • ledragonledragon Member ✭✭
    edited July 29

    I Am seeing all kinds of weirdness here. Just noticed that if I've amended some of the entry's values then scroll down and back up...the entries set in focus when I scroll them back into view. i.e. so one entry is focused then another is focused which must unfocus the previous one.

    BTW I'm using Listview with DataTempates

  • NMackayNMackay GBInsider, University mod

    @ledragon said:

    @NMackay said:
    That sounds very messy. You might be better creating a composite control (ContentView) with the Entry and add some attached bindings such as TextValue and ValidEntryCommand, handle the checks in the composite control and only fire the command when your conditions are satisfied.

    Also watch entries in a Listview Android in Marshmallow, if they have focus and you rotate the device...dark stuff can happen...certain in Forms 3.4 (it's an easy renderer fix) on devices with Touchwiz (S5 etc)

    Thanks for the reply.

    I'll have a look into a composite control. Do you know of a good link I can use for reference? ;-) I'm on forms v3.6 but it could be related. Actually the Android v8 device I don't see the issue on is an s8. The v6 is a Motorola Moto E.

    I was tempted by this:

    http://prismlibrary.github.io/docs/composite-commands.html

    Would you recommend me away from this then?

    I've used composite commands but it's really not meant for this, if you have multiple entries in the listview it could get very messy and you have to ensure you unregister the commands (like EventAggregator) by implementing IDestructible in your ViewModel (memory management tip).

    There's a few guides out there for creating your own controls
    https://mindofai.github.io/Creating-Custom-Controls-with-Bindable-Properties-in-Xamarin.Forms/

  • ledragonledragon Member ✭✭
    edited July 29

    Yes, there could be multiple entries in the listview (it's a dynamic data capture form it's all user defined). Do you have to unregister "regular" EventToCommandBehaviours? I'm not doing that ATM.

    Is it worth trying to figure out why this weirdness is happening (not that I know how I'd do that!) or is it a case of accepting it and finding a workaround?

    Thanks for your comments so far!

  • ledragonledragon Member ✭✭

    Also is there a reason to use ContentView for the composite control rather than creating a CustomControl with additional Bindable Properties that inherits from Entry?

    Ta!

  • ledragonledragon Member ✭✭

    https://github.com/xamarin/Xamarin.Forms/issues/1600

    FYI looks like this is the same issue I'm experiencing.

  • NMackayNMackay GBInsider, University mod

    @ledragon said:
    Also is there a reason to use ContentView for the composite control rather than creating a CustomControl with additional Bindable Properties that inherits from Entry?

    Ta!

    No, you could do it this way, actually probably a better approach

  • NMackayNMackay GBInsider, University mod

    @ledragon said:
    https://github.com/xamarin/Xamarin.Forms/issues/1600

    FYI looks like this is the same issue I'm experiencing.

    Thanks for the heads up. TBH we use Syncfusion controls (and Telerik on previous projects), the vanilla listview is just too flaky....for enterprise mobile dev anyway.

  • ledragonledragon Member ✭✭

    @NMackay said:
    Thanks for the heads up. TBH we use Syncfusion controls (and Telerik on previous projects), the vanilla listview is just too flaky....for enterprise mobile dev anyway.

    Hmm...I've got the Syncfusion library...maybe I'll try using that. Just banging my head against the wall with this....complete showstopper for my app. Looks like it's been a known issue for 18 months now!

    Cheers for the nugget!

  • ledragonledragon Member ✭✭

    Awesome! Same problem with Syncfusion Listview although now Entries focus on scrolling in Android v8 too!

  • ledragonledragon Member ✭✭

    @NMackay

    Hi Again! ;-) Hope you don't mind me pestering you...I'm seeing that the Entries are focusing as they're scrolled into view in the ListView. Only seems to happen if the Entry has previously had focus though. And weirdly if one Entry in the ListView has had focus then the others will focus on scroll too.

    Would you know of any way to prevent this? Is it default behaviour I can disable?

  • NMackayNMackay GBInsider, University mod

    Pass, I don't know of the top of my head and don't have time to research.

    It may be something to do with how the Entry is handled in LIstview cell recycling, you might have to dig into the Entry renderer using a custom renderer and maybe handle the focus issues there. That's where I'd be looking next if the default Entry behaviour is proving problematic in a Listview.

  • ledragonledragon Member ✭✭

    @NMackay said:
    Pass, I don't know of the top of my head and don't have time to research.

    It may be something to do with how the Entry is handled in LIstview cell recycling, you might have to dig into the Entry renderer using a custom renderer and maybe handle the focus issues there. That's where I'd be looking next if the default Entry behaviour is proving problematic in a Listview.

    Yeah trying that now. Thanks for the reply. Will post an update if I figure anything useful out.

Sign In or Register to comment.