Forum Xamarin.Forms

IsNavigatable property to allow navigation between different controls

ahmadmadiahmadmadi USMember ✭✭✭

Summary

Adding the ability to navigate between controls inside a layout or a grid , by navigation here I mean to set the focus/highlight controls inside the layout or Grid.

API Changes

  1. To add a boolean property inside the layout/grid to allow it's children to be navigatable or not
  2. To add integer property, (Attached Property), for the child controls that would be navigatable to indicate the order of nagivation (the order of who gets the "SetFocus" first )

e.g.

<StackLayout x:Name ="NavigatableLayout" IsNavigatable="True">
    <Button Text = "First"  StackLayout.NavigationOrder = "0"/>
    <Button Text = "Second" StackLayout.NavigationOrder = "1" />
</StackLayout>

Intended Use Case

This way it would make it much easier to navigate between controls by using arrows (Up and Down) when using a keyboard and remote control . This will be very helpful when making apps for TVs or TV Boxes .

Tagged:

Open · Last Updated

Posts

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Also more helpful for accessibility - IE: Handicapped screen readers and voice commands such as "next... next..."
    In the WPF world this was "TabOrder" and came up from WinForms. Its a very common use-case. Even without remotes or TV metaphore its nice on a page to enter text (as in a password) hit [tab] on the keyboard and be taken to the [LOGIN] button or to tab through fields on a form.

  • DaveParkerDaveParker GBUniversity

    This type of thing would also help with setting the "Next", "Done" key on the keyboard.

  • ahmadmadiahmadmadi USMember ✭✭✭

    @DaveParker For that there is already and event in Entry called "Completed" which you can use so you can set focus on something else than the entry

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @ahmadmadi
    That event doesn't help you specify anything for navigation. It only says when then keyboard input on an Entry is Completed. Does nothing for a DatePicker, Switch or other controls that someone would typically tab through when completing input on a page.

  • ahmadmadiahmadmadi USMember ✭✭✭

    @ClintStLaurent I know , it tells you when the user presses Return on the keyboard , the software keyboard, but then you can set focus on other stuff like DatePicker, switch , or anohter Entry .
    I used "Completed" to move from "Username" entry , to "Password" entry . And then from "PasswordEntry" to set focus on LoginButton So the user would just press ok button on his keyboard or remote control

  • NMackayNMackay GBInsider, University mod

    I'd agree this would be a really nice addition to the framework, currently you need to write a bunch of code to handle setting focus.

    Just don't copy the focus manager from WPF as it's horrible :smile:

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @ahmadmadi said:
    @ClintStLaurent I know , it tells you when the user presses Return on the keyboard , the software keyboard, but then you can set focus on other stuff like DatePicker, switch , or anohter Entry .
    I used "Completed" to move from "Username" entry , to "Password" entry . And then from "PasswordEntry" to set focus on LoginButton So the user would just press ok button on his keyboard or remote control

    The point is you shouldn't be writing a bunch of code behind. Doing that is basically wrong - or at the very least like writing 1990's WinForms code.

    At a framework level if controls can take some sort of TabOrder property then focus can shift automatically when a value is picked, Entry.Completed event raised etc. As well as through a simple command of Next instead of having to hard code the sequence in code behind like it was 1995.

  • ahmadmadiahmadmadi USMember ✭✭✭

    @ClintStLaurent the code behind is a partial class of the Xaml. So for me it is not wrong to write code in the code behind as long as it has nothing to do with business logic. For example, I would not change the color of a button if the Age is above 40 in the code behind. Of course if you can write this code in Xaml then it would be "prettier" and "cleaner" not more right or less wrong. As I said, the Xaml and code behind are one class and the code behind part is there to support the xaml part of the view.

    I agree with you that with "TabOrder" or "NavigatableLayout" would make things much easier and that is why I made this suggestion .

    Anyway lets not debate about coding style :P

  • DaveParkerDaveParker GBUniversity

    @ahmadmadi yep, already aware of that event. In the process of writing a lot of boring code to handle this. And completed doesn't help in that sense - I have to know the order of controls to set the correct text/option on the entry to get the keyboard to show the correct value - unless I have it completely wrong - which I'm sure I don't.

    Your proposal for adding a navigation/tabOrder suggests an awareness in the container of its child controls and how they should be navigated or have I misunderstood?

    If I am correct, it would also help manage the soft keyboard "next"/"done" type options as they also would seem to fall within the remit of such a pattern given that the container would know the ordering of controls and which one to go to "next".

    Sure, TV remotes and hard keyboards are one input option but so is the soft keyboard.

    Honestly, working in Angular/Jquery a lot and coming back to Xamarin.... I'm really missing the concept of a form and validators.... :)

  • DaveParkerDaveParker GBUniversity

    @ClintStLaurent - 1995... A bit earlier than that I reckon - even VB3 had tab order and that came out in about 1992/1993... ;)

  • ahmadmadiahmadmadi USMember ✭✭✭

    @DaveParker Honesly I have zero knowledge about Angular/Jquery so for me in this case I am happy for my ignorance (kidding)

    You are absolutly right ,that what I meant , plus the ability to turn the navigation on and off (if there is no need for that ) .

    The nice thing with "Next" or "Done" is that it is only one direction , however with remote control or a keyboard there at least two directions "Up/Down" or "Left/Right" so basicaly that boring code would be doubled in my case , however I solved in , with being humble, smart way , which is to have a list in the code behind and add all the controls you need to set the focus on this this list , with having a variable that has the index of the current Item in the list. So once you press next you basically do this

     currentIndex++;
    FocusableControls[currentIndex].Focus();
    

    Of course you will need to add some validation about what would happen when you reach the the last control .

    I seriously deserve a nobel prize

  • DaveParkerDaveParker GBUniversity

    @ahmadmadi I get you. I'm taking a similar approach but honestly, I'd rather spend my time doing business code... And @ClintStLaurent is 100% right on the need to for better accessibility support... I think I saw something about that being improved in another post but the two things go nicely together.

    Lets hope this gets some love and attention!

  • ChaseFlorellChaseFlorell CAInsider, University mod

    Hey, just as an FYI, this is easily accomplished with a Behavior if you need it. After the behavior is created, there's not much additional code to adding it to any Entry.

    public class FocusOnReturnBehavior : Behavior<Entry>
    {
        public VisualElement FocusOn{get;set;}
    
        protected override void OnAttachedTo(Entry bindable)
        {
            base.OnAttachedTo(bindable);
            bindable.Completed += BindableOnCompleted;
        }
    
    
        protected override void OnDetachingFrom(Entry bindable)
        {
            base.OnDetachingFrom(bindable);
            bindable.Completed -= BindableOnCompleted;
        }
    
        private void BindableOnCompleted(object sender, EventArgs args)
        {
            FocusOn?.Focus();
        }
    }
    

    Usage:

    <Entry x:Name="Foo">
        <Entry.Behaviors>
            <FocusOnReturnBehavior FocusOn="{x:Reference NextFoo}" />
        </Entry.Behaviors>
    </Entry>
    
    <Entry x:Name="NextFoo" />
    
  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @ChaseFlorell
    That's pretty clever. I like it. Thanks for sharing that with the community. Great stop-gap until a framework-wide solution can be created for all control types.

  • NMackayNMackay GBInsider, University mod

    @ChaseFlorell

    Nice solution. Remember to clear them all when popping the page.

Sign In or Register to comment.