Entry Focus Xamarin Forms MVVM

ElPiponElPipon COMember ✭✭
edited June 27 in Xamarin.Forms

I need focus a entry after of click a button.

I has think in implement a Behavior but i dont know that is the problem.

This is my code.

View.

Behavior Class.

`public class EntryFocusBehavior : Behavior
{
public bool OnFocus { get; set; }

    protected override void OnAttachedTo(Entry bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.TextChanged += OnEntryTextChanged;
    }

    protected override void OnDetachingFrom(Entry bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.TextChanged -= OnEntryTextChanged;
    }



    void OnEntryTextChanged(object sender, TextChangedEventArgs e)
    {
        var entry = (Entry)sender;

        if (OnFocus)
        {
            entry.Focus();
        }
        else
        {
            entry.Unfocus();
        }
    }
}`

And viewmodel.

public bool OnFocus { get; set; }

OnFocus ="True or False"

I need use PropertyChanged in view model binding??

Binding control is two away?

Thanks by help me forum community.

Posts

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    That kind of UI specific behavior doesn't belong in a VIewModel. A ViewModel could be the binding context of 10 different views. Or none.

    If you're going to do it anywhere it would be in the code behind of the view - since the expectation is for that view - not the the logic which is UI agnostic.. Keep UI to UI.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭
    I think you can use MessagingCenter. In your view model you should have the button's click command. There you should send a message to your UI. When your UI receive the message, set the Focus in the entry
  • ElPiponElPipon COMember ✭✭
    edited June 27

    @AlessandroCaliaro How can use MessagingCenter? You have a example, please.

    I dont know of this topic.

  • ElPiponElPipon COMember ✭✭

    @AlessandroCaliaro @ClintStLaurent guys i can`t message method dont work me.

    I am look the example of @NMackay https://forums.xamarin.com/discussion/32270/how-can-i-set-the-focus-and-display-the-keyboard-on-entry-control

    But there are things of method that i dont know do that.

    Can help me being more specific

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Being frank: MessageCenter does work. Its not broken.
    There is a lot of material out there on how to use it. There isn't much we can do about "I don't grasp it". There is a learning curve to development in general and Xamarin specifically. It will just take you time and practice to learn.

  • ElPiponElPipon COMember ✭✭
    edited June 28

    Ok guys, i have other solution.. this work for me in MVVM .

    1. Create a static object in page.xaml.cs:

      static Ingresar instance;

    2. Create a method static of you classname.

      public static page GetInstance()
      {
      if (instance == null)
      {
      instance = new page();
      }
      return instance;
      }

    3. Create a basic method with nameentry.focus()

    4. In constructor write the next code:

    instance = this

    1. After, you should create a var where you call to GetInstance() in ViewModel

    2. Last, you call the basic method that you create in CodeBehind

    Post: You need declare a x:Name in entry control.

    Success in you code.

    Greeting to Juan Carlos Zuluaga Teacher in Xamarin Forms from Medellin Colombia.

    https://www.youtube.com/user/jzuluaga55

  • JohnHardmanJohnHardman GBUniversity ✭✭✭✭✭

    @ElPipon - I don't understand that last post.

    Going back to the original question, @ClintStLaurent is correct - all you need is to call entryInstance.Focus() from the Button's OnClick handler in the code-behind.

                Button btnPutFocusOnEntry = new Button
                {
                    Text = "Put focus on Entry",
                    Command = new Command(() => { entry.Focus(); })
                };
    

    In scenarios where you are moving focus from one Entry to another (which would normally be in a Completed handler), you might need to call Unfocus() on the previous Entry before calling Focus() on the next Entry, but that's presumably not the case here.

    There is an extra complication, in that you might want to scroll the page before putting the focus onto the next Entry. There are confirmed bugs in Bugzilla that impact this scrolling currently, but that's extra complexity on top of what you asked about.

  • CarLoOSXCarLoOSX USMember ✭✭

    This is an example of how I do, before this I used to do using MessagingCenter

    in xaml , you need to give an x:Name to the obj you want to make focus.

        <!-- PICKER's DEFINITION -->
        <DatePicker
            x:Name="Datepicker"
            Date="{Binding SelectedDate, Mode=TwoWay}"
            IsEnabled="true"
            IsVisible="false">
        </DatePicker>
    

    then you have to make reference to that control in your command parameter on a button or for example in this case I use a toolbar item.

    <!-- MENU TOOLBAR -->
    <ContentPage.ToolbarItems>
        <ToolbarItem
            Command="{Binding ShowCalendarCommand}"
            Icon="Calendar"
            CommandParameter="{x:Reference Datepicker}" />
    </ContentPage.ToolbarItems>
    

    then in your vm command :

            #region toolbar commands
    
            public ICommand ShowCalendarCommand => new RelayCommand<Object>(ShowCalendar);
    
            #endregion
    
            private void ShowCalendar(Object obj)
            {
                var calendar = (DatePicker)obj;
                calendar.Focus();
                //  MessagingCenter.Send(this, "Calendar");
            }
    
  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    The issue with that approach is it violates the separation between View and ViewModel. A ViewModel isn't supposed to know anything about your viewS you could have 20 views binded to the same ViewModel - or none.

    You're making an assumption in your command that there even is a view. The very name "ShowCalendar" is a problem - Having a method that micromanages UI is a problem... because a ViewModel shouldn't be controlling UI - that's not how good MVVM is architected.

    Showing and hiding UI elements is by its very nature UI layer and should be handled in UI not in a ViewModel.

Sign In or Register to comment.