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); } } } }
作者:菩提树下的杨过
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。