ScrollViewer TextBlock中的键盘导航

时间:2012-04-30 16:05:05

标签: wpf

我在它周围的滚动查看器中有一个Textblock。我的应用程序完全由远程控制,因此在此上下文中,使用键,向上,向下,向左和向右执行导航。

我可以导航到Textblock但我被困在那里。我已经尝试过在每次控制中放置KeyboardNavigation.DirectionalNavigation =“Continue”,但我没有乐趣。

然后我考虑制作一个扩展滚动条或滚动查看器的自定义控件。 如果扩展滚动条,我可以按照以下方式覆盖keydown。

protected override void OnPreviewKeyDown(KeyEventArgs e)
    {
        if (this.Orientation == Orientation.Vertical)
        {
            if (e.Key == Key.Up)
            {
                if (this.Value == this.Minimum)
                {
                    this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Up));
                    e.Handled = true;
                }
            }
            if (e.Key == Key.Down)
            {
                if (this.Value == this.Maximum)
                {
                    this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
                    e.Handled = true;
                }
            }
            if (e.Key == Key.Left)
            {
                this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Left));
                e.Handled = true;
            }
            if (e.Key == Key.Right)
            {
                this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right));
                e.Handled = true;
            }
        }

        if (this.Orientation == Orientation.Horizontal)
        {
            if (e.Key == Key.Left)
            {
                if (this.Value == this.Minimum)
                {
                    this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Left));
                    e.Handled = true;
                }
            }
            if (e.Key == Key.Right)
            {
                if (this.Value == this.Maximum)
                {
                    this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right));
                    e.Handled = true;
                }
            }
            if (e.Key == Key.Up)
            {
                this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Up));
                e.Handled = true;
            }
            if (e.Key == Key.Down)
            {
                this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
                e.Handled = true;
            }
        }
        base.OnPreviewKeyDown(e);
    }
}

问题是我不知道如何更改ScrollViewer滚动条以使用自定义滚动条,或者即使按下某个键时上面的代码甚至会触发。我认为文本块和scrollviewer将是看到事件的控件。

有没有办法在上面的代码中执行类似于Scrollviewers代码的操作?

1 个答案:

答案 0 :(得分:1)

我最终通过创建自定义控件解决了这个问题。如果滚动查看器可以按下按键的方向滚动,我会计算出来。如果是,则事件将传递到基础滚动查看器。如果不是,则事件被标记为已处理,并且焦点沿按键方向移动。

public class KNScrollViewer : ScrollViewer
{
    static KNScrollViewer()
    {

    }

    private bool canScrollUp
    {
        get
        {
            return this.ScrollableHeight > 0 && this.VerticalOffset > 0;
        }
    }

    private bool canScrollDown
    {
        get
        {
            return this.ScrollableHeight > 0 &&
              this.VerticalOffset + this.ViewportHeight < this.ExtentHeight;
        }
    }

    private bool canScrollLeft
    {
        get
        {
            return this.ScrollableWidth > 0 && this.HorizontalOffset > 0;
        }
    }

    private bool canScrollRight
    {
        get
        {
            return this.ScrollableWidth > 0 &&
            this.HorizontalOffset + this.ViewportWidth < this.ExtentWidth;
        }
    }

    public bool CanScroll
    {
        get
        {
            if (canScrollUp || canScrollDown || canScrollLeft || canScrollRight)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    protected override void OnPreviewKeyDown(KeyEventArgs e)
    {
        if (e.Key == Key.Up)
        {
            if (!canScrollUp)
            {
                this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Up));
                e.Handled = true;
            }
        }
        if (e.Key == Key.Down)
        {
            if (!canScrollDown)
            {
                this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
                e.Handled = true;
            }
        }
        if (e.Key == Key.Left)
        {
            if (!canScrollLeft)
            {
                this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Left));
                e.Handled = true;
            }
        }
        if (e.Key == Key.Right)
        {
            if (!canScrollRight)
            {
                this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right));
                e.Handled = true;
            }
        }
    }
}