前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Silverlight:ScorllViewer随Tab键自动跟随子控件的Focus滚动

Silverlight:ScorllViewer随Tab键自动跟随子控件的Focus滚动

作者头像
菩提树下的杨过
发布2018-01-23 17:05:21
1.2K0
发布2018-01-23 17:05:21
举报
文章被收录于专栏:菩提树下的杨过

当ScrollViewer里包含很多子控件时,默认情况下只能用鼠标手动拖动(或滚轮)滚动条以实现内容的滚动,假如用户是键盘高手,习惯于用Tab键来切换子控件焦点时,即使当前获得焦点的控件在不可见区域,滚动条也不会自动跟随着滚动到相应位置,这个非常不方便,今天在网上看到一个老外的解决办法,代码转贴于此:

代码语言:javascript
复制
        private void _ScrollViewer_GotFocus(object sender, RoutedEventArgs e)
        {
            FrameworkElement element = e.OriginalSource as FrameworkElement;

            if (element != null)
            {
                ScrollViewer scrollViewer = sender as ScrollViewer;
                scrollViewer.ScrollToVerticalOffset(GetVerticalOffset(element, scrollViewer));
            }

        }

        private double GetVerticalOffset(FrameworkElement child, ScrollViewer scrollViewer)
        {
            // Ensure the control is scrolled into view in the ScrollViewer.  
            GeneralTransform focusedVisualTransform = child.TransformToVisual(scrollViewer);
            Point topLeft = focusedVisualTransform.Transform(new Point(child.Margin.Left, child.Margin.Top));
            Rect rectangle = new Rect(topLeft, child.RenderSize);
            double newOffset = scrollViewer.VerticalOffset + (rectangle.Bottom - scrollViewer.ViewportHeight);
            return newOffset < 0 ? 0 : newOffset; // no use returning negative offset 
        } 

  即:给ScrollViewer的GotFocus事件增加_ScrollViewer_GotFocus处理方法,然后计算当前获取焦点的控件与ScorllViewer的偏移距离,最终得出滚动条应该滚动的偏移量。

上面这一段代码基本上能解决问题,但是有一个小小的不足:如果有3个输入框从上到下排着,且都在可视范围内,这时如果用鼠标去点击其中一个不是当前获得焦点的输入框,也会触发以上代码,导致滚动条跳动一段距离,这个给用户的感觉好象界面总是在“发神经的”抖动。

静下来细想一下:其实我们的本意是要解决用户按TAB键的问题,只要在KeyDown或KeyUP事件里处理就行了,没必要在GetFocus时处理,于是有了下面的改进版:

代码语言:javascript
复制
<UserControl x:Class="SilverlightApplication2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <ScrollViewer Height="200" Width="200" KeyUp="ScrollViewer_KeyUp">
            <StackPanel>
                <Button Content="1" Height="20" />
                <Button Content="2" Height="20" />
                <Button Content="3" Height="20" />
                <Button Content="4" Height="20" />
                <Button Content="5" Height="20" />
                <Button Content="6" Height="20" />
                <Button Content="7" Height="20" />
                <Button Content="8" Height="20" />
                <Button Content="9" Height="20" />
                <Button Content="10" Height="20" />
                <Button Content="11" Height="20" />
                <Button Content="12" Height="20" />
                <Button Content="13" Height="20" />
                <Button Content="14" Height="20" />
                <Button Content="15" Height="20" />
                <Button Content="16" Height="20" />
                <Button Content="17" Height="20" />
                <Button Content="18" Height="20" />
                <Button Content="19" Height="20" />
                <Button Content="20" Height="20" />
            </StackPanel>
        </ScrollViewer>

    </Grid>
</UserControl>

  cs部分:

代码语言:javascript
复制
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace SilverlightApplication2
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void ScrollViewer_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Tab)
            {
                ScrollViewer scrollViewer = sender as ScrollViewer;
                FrameworkElement focusedElement = FocusManager.GetFocusedElement() as FrameworkElement;
                GeneralTransform focusedVisualTransform = focusedElement.TransformToVisual(scrollViewer);
                Rect rectangle = focusedVisualTransform.TransformBounds(new Rect(new Point(focusedElement.Margin.Left, focusedElement.Margin.Top), focusedElement.RenderSize));
                double newOffset = scrollViewer.VerticalOffset + (rectangle.Bottom - scrollViewer.ViewportHeight);
                scrollViewer.ScrollToVerticalOffset(newOffset);
            }

        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2011-10-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档