まず、自分の限界と達成しようとしていることを詳しく説明する必要があると思います。それがなければ、あなたがしていることがうまくいかない理由を説明することしかできません。あなたが求めている結果を得る方法について、誰かがより良い考えを持っているかもしれません.
ListBoxの中に入れた場合ScrollViewer、 のコントロール テンプレートにはListBoxまだ独自のScrollViewer内部があります。マウス カーソルが の上にあり、マウスListBoxホイールをスクロールすると、そのイベントがScrollViewerの一部に到達するまでバブル アップしListBoxます。それはスクロールによってそれを処理し、イベントを処理済みとしてマークするので、ScrollViewerイベントListBoxを無視します。
ListBox外側よりも背を高くして狭くしScrollViewer、それ自体が項目をスクロールできるように十分な項目を与えると、ListBox2 つの垂直スクロール バーが表示ListBoxさListBoxれますScrollViewer。マウス カーソルが の内側にあるListBox場合、ListBoxはその内部の でアイテムをスクロールし、ScrollViewerそのBorder場所にとどまります。マウス カーソルがアウターのListBox外側と内側にある場合ScrollViewer、ScrollViewerその内容がスクロールListBoxされます。ListBoxBorder
アウターでコントロール全体 (アイテムだけでなく も含む)ScrollViewerをスクロールする場合は、 のスタイルを変更して internal を持たないようにする必要がありますが、自動的に取得されるようにする必要もあります。アイテムによっては大きくなります。ListBoxBorderListBoxScrollViewer
いくつかの理由から、このアプローチはお勧めしません。ScrollViewer内にと一緒に他のコントロールがある場合は意味があるかもしれListBoxませんが、サンプルはそれを示していません。また、 に多くの項目があるListBox場合は、すべての項目に対して を作成することになり、既定の が原因ListBoxItemで再スタイルされていない既定の利点が失わListBoxれますVirtualizingStackPanel。
お客様の実際の要件をお知らせください。
編集: OK、これらの画像を追加することで、もう少し良いアイデアが得られました。あなたが得ている効果は、スクロールするのに十分なアイテムがあり、スクロールバーが表示されると、利用可能な領域が水平方向に少し縮小する必要があるということScrollViewerですGrid. これらは、少ないものから良いものへの順序で、あなたのオプションのようです:
ListBoxを持たないように を再スタイルし、再スタイルした を の外でScrollViewer使用します。また、同じ 内のすべてのアイテムを表示するのに十分な高さを強制する必要があり、UI の仮想化が失われます。リストに何百ものアイテムを表示する場合、それを失いたくはありません。ScrollViewerListBoxListBoxStyle
- のスタイルを変更し、スクロールバーを別の列ではなくコンテンツの上に配置する、作成済みのスタイルでを使用するように
ListBoxを設定します。これは問題ありません (高さを制限し、 を使用するようになります) が、あなたが言ったように、.ControlTemplateScrollViewerListBoxVirtualizingStackPanelDataTemplate
- のスタイルを変更して、
ScrollViewer表示されていない場合でも垂直スクロール バー用のスペースを残します。このオプションは次のようになります。
デフォルトでは、これに相当するScrollViewer2 つの列を使用します。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。