Scroll datagrid by keyboard in c#/wpf

45 views Asked by At

I have small app using only barcode scanner and numpad keyboard. For this reason is force focus to textbox (txtInput) and all application control is done via the keydown event for this textbox.

After scan of bacode, it's showed content of box. Now i scan more codes and they add or subtract from the contents of the box. I display the contents of that box in the datagrid.

The problem is when the content of the box is larger than it fits on the screen. I need to scroll the datagrid with keys. Now I have it done like this:

UInt16 list = 1;

private void txtInput_KeyDown(object sender, KeyEventArgs e)
{
  if (e.Key == Key.Enter)
  {
    // process of barcode
  }
  else if (e.Key == Key.Add)
  {
    if(list < dataGridTickets.Items.Count)
    {
        dataGridTickets.ScrollIntoView(dataGridTickets.Items[list]);
        list++;
    }
  }
  else if (e.Key == Key.Subtract)
  {
    if(list > 1)
    {
         dataGridTickets.ScrollIntoView(dataGridTickets.Items[list - 2]);
         list--;
    }
  }
}

It's working, but I have to press the plus key 20 times before I reach the bottom item and it starts scrolling down. The same problem when I want to scroll back.

Is there another way to scroll the datagrid than via an item based scrollintoview?

Is there a way to find out the number of displayed items so that I can add it to the "list" variable? (a different number of items will fit on a different display resolution)

Is there a way to programmatically control the position of the datagrid slider directly?

Or is there any other solution?

2

There are 2 answers

0
mm8 On

Is there a way to programmatically control the position of the datagrid slider directly?

If you get a reference to the internal ScrollViewer using the VisualTreeHelper:

private static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(obj, i);
        if (child != null && child is T)
        {
            return (T)child;
        }
        else
        {
            T childOfChild = FindVisualChild<T>(child);
            if (childOfChild != null)
                return childOfChild;
        }
    }
    return null;
}

...you could use its ScrollToVerticalOffset method to scroll to to a specified vertical offset position:

ScrollViewer scrollViewer = FindVisualChild<ScrollViewer>(dataGridTickets);
if (scrollViewer != null)
{
    scrollViewer.ScrollToVerticalOffset(200);
}

There is also a ScrollToBottom method and a ScrollToTop method if that's what you need. Or ScrollToEnd/ScrollToHome.

2
Gerry Schmitz On

You can add "key modifiers" (e.g. Shift and / or Ctrl), that expands the range of function of the keys you currently do support; e.g. Ctrl+DownArrow (or PageDown, etc) tells your "code behind" to scroll to the bottom.

In the same way, shift and space bar (key codes) could incrementally move a slider.

And the PreviewKeyDown event (at some parent level) tends to be more useful for "previewing" keypresses; and being able to "accept, process, pass along, and / or reject" any keypress before it complicates things (more).