私は上記のKirilの答えの助けを借りて、これを動作させました。これの一般的なコンテキストは、アプリケーションでユーザー定義可能なフォームがあり、このコードはフォーム上のコントロールをレンダリングするために使用されるということです。
私の一般的な戦略は、グリッドに私のコントロールを追加し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クラスにいくつかの有用な検索機能を追加し、私自身のクラスです。
おかげで - 少し修正して、私はそれが非常にうまく働いていた答えとして投稿します。 GeneralTransformのTransformBoundsメソッドはSL3のようです。 –
これは古い投稿であることは分かっていますが、私は同じことをやろうとしています。私はこのコードを使用していますが、Margin.LeftとMargin.Topの値は常に0です。スクロールするコントロールはScrollViewerのグリッドの内側にあり、コントロールはグリッド内にrowとrowspanのプロパティ値を渡して配置されます。 – Jeremy