誰かがこの動作についてより良い説明を持っていない限り、これは本当に奇妙なバグのように見えます。
ScrollViewer
(PART_ContentHost) は内部的に次のTemplate
ようなものを使用します:
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid x:Name="Grid"
Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle x:Name="Corner"
Grid.Row="1"
Grid.Column="1"
Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.Row="0"
Grid.Column="0"
Margin="{TemplateBinding Padding}"
CanContentScroll="{TemplateBinding CanContentScroll}"
CanHorizontallyScroll="False"
CanVerticallyScroll="False"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
<ScrollBar x:Name="PART_VerticalScrollBar"
Grid.Row="0"
Grid.Column="1"
AutomationProperties.AutomationId="VerticalScrollBar"
Cursor="Arrow"
Maximum="{TemplateBinding ScrollableHeight}"
Minimum="0"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding VerticalOffset,
Mode=OneWay,
RelativeSource={RelativeSource TemplatedParent}}" />
<ScrollBar x:Name="PART_HorizontalScrollBar"
Grid.Row="1"
Grid.Column="0"
AutomationProperties.AutomationId="HorizontalScrollBar"
Cursor="Arrow"
Maximum="{TemplateBinding ScrollableWidth}"
Minimum="0"
Orientation="Horizontal"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{Binding HorizontalOffset,
Mode=OneWay,
RelativeSource={RelativeSource TemplatedParent}}" />
</Grid>
</ControlTemplate>
興味深い点は次のとおりです。
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.Row="0"
Grid.Column="0"
Margin="{TemplateBinding Padding}"
CanContentScroll="{TemplateBinding CanContentScroll}"
CanHorizontallyScroll="False"
CanVerticallyScroll="False"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
問題を解決するには、代わりに Margin を 0 に設定するだけで{TemplateBinding Padding}
、目的の出力が得られます。
しかし、なぜそれを行う必要があったのでしょうか?
TemplateBinding Padding
内部スコープにあるに直接設定された値を無視しているようで、 15 でScrollViewer
ある Parent( ) から継承された Padding 値を選択しますButton
。
それは奇妙ですが、さらに悪いことに、これはパディング専用です。Foreground
、Background
、 にMargin
直接設定すると、のフィールドScrollViewer
が上書きされます。使用中のセットをデフォルトのスタイルセッターに直接TextBox
移動して、優先順位のケースが問題であるかどうかを確認することさえできました。Padding
TextBox
そうではないようでした。同じ出力を得ました。
パディングはSystem.Windows.Controls.Control
、Foreground と Background がScrollViewer
継承する同じクラスで定義されます。パディングだけで動作が異なる理由がわかりません。
また、プレゼンターを次のようなものに変更してみました
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.Row="0"
Grid.Column="0"
Margin="{TemplateBinding Margin}"
CanContentScroll="{TemplateBinding CanContentScroll}"
CanHorizontallyScroll="False"
CanVerticallyScroll="False"
Content="{TemplateBinding Padding}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
15,15,15,15 と表示されます。に対してはそうしませんMargin
。
{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}}, Path=Padding}
バインディングと同じ効果。
ScrollViewer
私は、それに設定されたプロパティをその子に渡さないという投稿を見ました。もしそうなら、どうやってBackground
,Margin
を上書きしてもいいのでしょうか? 何がそんなに特別なのPadding
?それが有効な動作である場合、テンプレートを使用せずにその動作を取り除く方法が実際にはわかりません。これはScrollViewer
紛らわしい実装の 1 つです。