我怎样才能让Silverlight的ScrollViewer中滚动,以显示与焦点的子控件?

StackOverflow https://stackoverflow.com/questions/1225318

  •  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类

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top