Friday, February 03, 2012

Don't use the OnSelectionChanged event to trigger navigation #wp7dev

It's a comon practice. Hey, it' even in some of the default templates.

But don't attach an event handler to the `OnSelectionChanged` (or equivalent `OnSelectedItemChanged`) events and then use this as the trigger for  starting navigation.

This is typically used when there are options displayed in a list[box] and the user can select an item to navigate to the appropriate page. It's also really common for such a list to be large enough that the user must scroll to see all the items. Therein lies the problem. It's common for the first part of the swipe gesture (intended to scroll the list) to be interpreted as a selection. This then causes the app to navigate to the item that was touched while swiping, not the one the user actually wanted.

Instead, add a handler for the `Tap` event of the individual item. This way you don't risk confusing the gestures.

This way you'll have an app that behaves as the user expects. This is definitely a step towards having happier users which will hopefully help lead to you havinng more of them.

6 comments:

  1. Demo needed to persuade me (I'll do one myself in my "spare time"!)

    ReplyDelete
  2. @MunkiiYebee1:41 pm

    @Slodge mr.lacey speaks the truth. If you want another reason imagine that you trigger your nav based on the ListBox selected item changing.

    1. User selects item 2 and you nav to child page X and display item 2. Nice

    2. User presses Back and they come back to the same listbox

    3. User thinks "oooops I need to look at item 2 some more"

    4. Press item 2

    5. Nothing happens, no nav, user starts to cry.

    Why? because the selection was set to item 2 in step 1 and never changes it is still item 2 as step 4 happens. Selection does not chnage and your nav never fires.

    ReplyDelete
  3. @MunkiiYebee - Yes, this solves that problem too. :)

    Selecting something in a list is not the same as wanting to navigate to the place represented by that item in the list. The difference is subtle, but important.

    You should select something if you want to subsequently perform an action with teh selected item or change something else on the same page in relation to the selection. (Such as display details in a master-detail relationship. - But that's typically hard to do on a small screen.)

    ReplyDelete
  4. @MunkiiYebee - I always just work around that problem by resetting the SelectedIndex before I navigate. I've got to admit the reason I use SelectedIndex is because one of the appwizard basic templates did when I first started... but beyond that I still would need to actually see a demo where there was a difference...

    ReplyDelete
  5. Run the appwizard for Pivot.

    Change pivot 1 to use:
    SelectionChanged="FirstListBox_SelectionChanged"

    Change pivot 2 datatemplaet to use:


    Change the code behind to:

    private void FirstListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
    if (((ListBox)sender).SelectedIndex == -1)
    return;

    MessageBox.Show("Selection");
    ((ListBox)sender).SelectedIndex = -1;
    }

    private void StackPanel_Tap(object sender, GestureEventArgs e)
    {
    MessageBox.Show("Tap");
    }


    I honestly can't see any difference running on the phone... can you? (What gesture am I missing?)

    ReplyDelete
  6. Please note that `ListBoxItem` has a `Tap` event. Do not use the `GestureListener` to detect a tap. In fact, don't use the GestureListener at all. It has potentially nasty issues including performance implications.
    Thank you please.

    ReplyDelete

I get a lot of comment spam :( - moderation may take a while.