13

複数のコントロールを持つ Grid を含む ScrollViewer があります。ユーザーはコントロールをタブで移動できますが、最終的には表示されていないコントロールにタブ移動するため、コントロールを再び表示するには手動でスクロールする必要があります。

フォーカスされたコントロールが常に表示されるように、ScrollViewer を自動的にスクロールさせる方法はありますか。それができない場合、すべてのコントロールで GotFocus イベントをリッスンしてから ScrollViewer をスクロールしてコントロールを表示する以外に、これを機能させる方法はありますか?

現在、Silverlight 2 を使用しています。

4

4 に答える 4

11

Silverlight ツールキットには、"ScrollIntoView" メソッドが含まれています。

System.Windows.Controls.Toolkit.dll への参照を追加すると、以下のコードを使用できるようになります。

scrollViewer.ScrollIntoView(control);

于 2010-11-16T13:59:27.310 に答える
3

ほんの少しの強化。ちなみに、Silverlight 4 ではまだこれを行う必要があります。各コントロールの GotFocus の代わりに、スクロールビューア自体の 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
        }
于 2010-07-08T19:31:56.763 に答える
1

上記のキリルの答えの助けを借りて、これを機能させました。これの一般的なコンテキストは、アプリケーションにユーザー定義可能なフォームがあり、このコードはフォーム上のコントロールをレンダリングするために使用されるということです。

私の一般的な戦略は、コントロールを Grid に追加し、次に VisualTreeHelper を使用して ScrollViewer のすべての子を見つけ、各コントロールに GotFocus イベント ハンドラーを追加することでした。

コントロールがフォーカスを取得したら、再び VisualTreeHelper を使用してビジュアル ツリーを検索し、ScrollViewer によってスクロールされている Grid を親とするコントロールを見つけます。次に、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 クラスに追加する独自のクラスです。

于 2009-08-04T20:34:32.430 に答える