zoukankan      html  css  js  c++  java
  • Silverlight:ScorllViewer随Tab键自动跟随子控件的Focus滚动

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

            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时处理,于是有了下面的改进版:

    <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部分:

    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);
                }
    
            }
        }
    }
    

      

  • 相关阅读:
    数组相关操作
    控制结构和函数
    调用函数和方法
    常用类型、算术和操作符重载
    函数式 CSS (FCSS)
    Javascript 封装问题
    认识javascript中的作用域和上下文
    Javascript 继承-原型的陷阱
    解耦你的HTML,CSS和JAVASRIPT
    网格如此简单
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/2215896.html
Copyright © 2011-2022 走看看