1
votes

I'm developing a program in WPF (VB) that relies on keyboard navigation only.

In my program, I have a listbox that displays up to 20000 items.

What I want is that when the listbox has keyboard focus, and I move to the bottom item that is visible (using ArrowDown), I want the focus to move to the next item outside the listbox. I'm using PgUp and PgDown to scroll the listbox contents, and text search to jump to items.

Is there a way to detect if the focused/selected item is the last/first visible item in the listbox?

If so, I could just use:

ListBox1.MoveFocus(New TraversalRequest(FocusNavigationDirection.Down))
3

3 Answers

2
votes

I'd suggest that you don't do this, the user interface should behave consitesntly with other user interfaces in the operating system.

Your users would be better off if you come up with an alternate user interface that's consistent with how user interfaces behave on your target operating system.

0
votes

It is a little clear from your explanation but either your looking for:

  1. navigation to move outside of the listbox when the last item is selected.
  2. when navigation is attempted beyond the last item in the list that the navigation pops out of the listbox.

If (1) is your objective there is probably a reasonable solution using triggers and or some custom code handling for events based on the selected item and selected item changed. I would have to agree with Tom if this is the case though and suggest that you do not implement it this way since the last item will never be selectable without focus being programatically removed.

If your instead looking to do (2) then it is my experience that the natural behavior of a ListBox is to move to the next control when the Tab key is pressed and I've tested this for the down arrow key as well and it works the same. When I get to the last item in the list focus pops out of the listbox and to the next control according to it's parent.

UPDATE: I have to withdraw my original comments as the behavior I described above do not describe the default behavior in WPF for a ListBox however it is the behavior you will see the behavior I described above (which I believe is the behavior your looking for) when implementing an ItemsControl and specifying an ItemTemplate. Take a look at the following example.

<ItemsControl ItemsSource="{Binding ElementName=TheWindow, Path=ListOStrings}">
    <ItemsControl.Template>
        <ControlTemplate TargetType="{x:Type ItemsControl}">
            <Border BorderBrush="Magenta"
                    BorderThickness="1">
                <ScrollViewer>
                    <ItemsPresenter />
                </ScrollViewer>
            </Border>
        </ControlTemplate>
    </ItemsControl.Template>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

By chance, this just happens to have the behavior you described since each item in the list behaves almost like a control placed directly as a peer to all the other controls.

0
votes

I use an easy trick to move the focus outside Listbox: I disable the listbox so the focus moves automatically to the next control, then i enable the listbox again :)

Lst.IsEnabled = False
Lst.MoveFocus(New TraversalRequest(FocusNavigationDirection.Next))
Lst.IsEnabled = True