まず、自分の限界と達成しようとしていることを詳しく説明する必要があると思います。それがなければ、あなたがしていることがうまくいかない理由を説明することしかできません。あなたが求めている結果を得る方法について、誰かがより良い考えを持っているかもしれません.
ListBox
の中に入れた場合ScrollViewer
、 のコントロール テンプレートにはListBox
まだ独自のScrollViewer
内部があります。マウス カーソルが の上にあり、マウスListBox
ホイールをスクロールすると、そのイベントがScrollViewer
の一部に到達するまでバブル アップしListBox
ます。それはスクロールによってそれを処理し、イベントを処理済みとしてマークするので、ScrollViewer
イベントListBox
を無視します。
ListBox
外側よりも背を高くして狭くしScrollViewer
、それ自体が項目をスクロールできるように十分な項目を与えると、ListBox
2 つの垂直スクロール バーが表示ListBox
さListBox
れますScrollViewer
。マウス カーソルが の内側にあるListBox
場合、ListBox
はその内部の でアイテムをスクロールし、ScrollViewer
そのBorder
場所にとどまります。マウス カーソルがアウターのListBox
外側と内側にある場合ScrollViewer
、ScrollViewer
その内容がスクロールListBox
されます。ListBox
Border
アウターでコントロール全体 (アイテムだけでなく も含む)ScrollViewer
をスクロールする場合は、 のスタイルを変更して internal を持たないようにする必要がありますが、自動的に取得されるようにする必要もあります。アイテムによっては大きくなります。ListBox
Border
ListBox
ScrollViewer
いくつかの理由から、このアプローチはお勧めしません。ScrollViewer
内にと一緒に他のコントロールがある場合は意味があるかもしれListBox
ませんが、サンプルはそれを示していません。また、 に多くの項目があるListBox
場合は、すべての項目に対して を作成することになり、既定の が原因ListBoxItem
で再スタイルされていない既定の利点が失わListBox
れますVirtualizingStackPanel
。
お客様の実際の要件をお知らせください。
編集: OK、これらの画像を追加することで、もう少し良いアイデアが得られました。あなたが得ている効果は、スクロールするのに十分なアイテムがあり、スクロールバーが表示されると、利用可能な領域が水平方向に少し縮小する必要があるということScrollViewer
ですGrid
. これらは、少ないものから良いものへの順序で、あなたのオプションのようです:
ListBox
を持たないように を再スタイルし、再スタイルした を の外でScrollViewer
使用します。また、同じ 内のすべてのアイテムを表示するのに十分な高さを強制する必要があり、UI の仮想化が失われます。リストに何百ものアイテムを表示する場合、それを失いたくはありません。ScrollViewer
ListBox
ListBox
Style
- のスタイルを変更し、スクロールバーを別の列ではなくコンテンツの上に配置する、作成済みのスタイルでを使用するように
ListBox
を設定します。これは問題ありません (高さを制限し、 を使用するようになります) が、あなたが言ったように、.ControlTemplate
ScrollViewer
ListBox
VirtualizingStackPanel
DataTemplate
- のスタイルを変更して、
ScrollViewer
表示されていない場合でも垂直スクロール バー用のスペースを残します。このオプションは次のようになります。
デフォルトでは、これに相当するScrollViewer
2 つの列を使用します。Grid
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
したがって、Width
スクロールバーが表示されていない場合、スクロールバーの列の は 0Width="Auto"
です。非表示の場合でもスクロールバー用のスペースを残すために、Width
その列の をWidth
垂直スクロール バーのにバインドします。
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition
Width="{Binding ElementName=PART_VerticalScrollBar, Path=Width}" />
</Grid.ColumnDefinitions>
したがってControlTemplate
、カスタムStyle
の forは次のScrollViewer
ようになります。
<ControlTemplate
TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition
Width="{Binding ElementName=PART_VerticalScrollBar, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition
Height="Auto" />
</Grid.RowDefinitions>
<ScrollContentPresenter />
<ScrollBar
Grid.Column="1"
Name="PART_VerticalScrollBar"
Value="{TemplateBinding VerticalOffset}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
<ScrollBar
Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="1"
Value="{TemplateBinding HorizontalOffset}"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
</Grid>
</ControlTemplate>
コンテンツ列を固定サイズにし、スクロールバー列を作成することもできますWidth="*"
。これは、画像が引き伸ばされていない場合、長期的にはうまく機能する可能性があります. DataTemplate
スクロールバーが表示されているかどうかにかかわらず、使用する一貫した領域を取得するため、スクロールバーの幅を補正する必要がなくなりました。
の例ControlTemplate
のScrollViewer
残りの部分を確認したくなるでしょうが、これらの例はデフォルトのスタイルではありません。この例では、垂直スクロールバーが左側に配置されていることに注意してください! についての下部のコメントにも注意してくださいContentScrollPresenter
。