DataGrid が 1 つあるウィンドウがあります。この DataGrid の DataGridColumnHeader はテンプレート化されています。
<Style x:Key="headerTxtBox" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border>
<ScrollViewer/>
</Border>
<Thumb Name="PART_LeftHeaderGripper">
...
</Thumb>
<Thumb Name="PART_RightHeaderGripper">
...
</Thumb>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
メイン ビュー:
<Window>
<Window.Resources>
...
</Window.Resources>
<DataGrid Loaded="GridOnLoaded"
ColumnHeaderStyle="{StaticResource headerTxtBox}"/>
</Window>
DataGrid.Loaded イベントのバックエンドで、ScrollContentPresenter.RequestBringIntoView にハンドラーを追加します。
private void GridOnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
ScrollContentPresenter scp = Utils.FindDescendant<ScrollContentPresenter>(_grid);
if (scp != null)
{
scp.RequestBringIntoView += ScpOnRequestBringIntoView;
}
}
問題:
テンプレートに ScrollViewer (TextBox など) を含むコントロールが含まれている場合、ScrollContentPresenter は RequestBrintIntoView イベントをキャッチしません。
テンプレートを変更して ScrollViewer を取り除くと、すべて正常に動作します。ScrollContentPresenter はすべての RequestBringIntoView をキャッチします。
RequestBringIntoView が発生したとき、私はすでにルートを調べました。どちらの場合もルートは同じです。そして、ScrollContentPresenter を通過します。ただし、最初のケースでは、RequestBringIntoView は、ScrollContentPresenter ではなく、ScrollContentPresenter の親 ScrollViewer によって処理されます。