我怎样才能让Silverlight的ScrollViewer中滚动,以显示与焦点的子控件?
-
22-07-2019 - |
题
我有一个的ScrollViewer其中包含与在它的多个控件的网格。罐用户通过控制选项卡,但他们最终标签到不考虑控制 - 。因此他们必须manully滚动使控制再次可见
有没有什么办法来自动进行的ScrollViewer滚动,使聚焦的控制始终是可见的。如果做不到这一点,有没有什么办法可以使这项工作,总之听上的每个控件的GotFocus事件,然后滚动的ScrollViewer使控制可见的?
目前我使用的Silverlight 2。
解决方案
<强>我测试此使用Silverlight 3.我不能肯定约SL2。强>
这是我的XAML:
<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>
和这是后台代码:
private void ScrollViewer_KeyUp(object sender, KeyEventArgs e)
{
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);
}
我所做的是对按键#1选项卡中单击,直到我到达按钮#20。它为我工作。给它一个尝试,让我知道它是如何为你工作。
其他提示
Silverlight工具包包含一个方法 “ScrollIntoView”。
的参考添加到System.Windows.Controls.Toolkit.dll ANS你应该能够使用下面的代码。
scrollViewer.ScrollIntoView(control);
仅有轻微的提高。还是需要的方式来做到这一点的Silverlight 4。 相反的GotFocus为每个控件可以处理的ScrollViewer本身的GotFocus和实施它只是一次。
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
}
我得到这个工作,上面基里尔的回答帮助。这样做的一般上下文是我在我的申请用户可定义的形式,并且该码被用于渲染窗体上的控件。
我的一般策略是我的控件添加到一个网格,然后使用VisualTreeHelper找到ScrollViewer中的所有孩子,并添加一个GotFocus事件处理程序的每个控制。
当控件获得焦点,再次使用VisualTreeHelper,我搜索了可视树找到其母公司是由ScrollViewer中滚动网格控制。然后我滚动的ScrollViewer使控制可见。
下面是代码(gridRender是网格的是,控制被添加到):
private void AfterFormRendered()
{
var controls = VisualTreeHelperUtil.FindChildren<Control>(gridRender);
foreach (var ctrl in controls)
{
ctrl.GotFocus += CtrlGotFocus;
}
}
private void CtrlGotFocus(object sender, RoutedEventArgs e)
{
var ctrl = sender as Control;
var gridChildControl = VisualTreeHelperUtil.FindParentWithParent(ctrl, gridRender) as FrameworkElement;
if (gridChildControl != null)
{
// Ensure the control is scrolled into view in the ScrollViewer.
GeneralTransform focusedVisualTransform = gridChildControl.TransformToVisual(scrollViewer);
Point topLeft = focusedVisualTransform.Transform(new Point(gridChildControl.Margin.Left, gridChildControl.Margin.Top));
Rect rectangle = new Rect(topLeft, gridChildControl.RenderSize);
double newOffset = scrollViewer.VerticalOffset + (rectangle.Bottom - scrollViewer.ViewportHeight);
scrollViewer.ScrollToVerticalOffset(newOffset);
}
}
请注意:该VisualTreeHelperUtil类是我自己的类,增加了一些有用的搜索功能到VisualTreeHelper类