首先,我认为您需要详细说明您的限制是什么以及您要达到的目标。没有那个,我只能解释为什么你正在做的事情不起作用。有人甚至可能对如何获得您所追求的结果有更好的想法。
如果你放在ListBox
一个里面ScrollViewer
,那么控件模板ListBox
仍然有它自己的里面ScrollViewer
。当鼠标光标在 上并且您滚动鼠标滚轮时,该事件会冒泡,ListBox
直到到达ScrollViewer
. ListBox
那一个通过滚动来处理它并将事件标记为已处理,所以ScrollViewer
你把它放在ListBox
里面会忽略该事件。
如果您使 theListBox
比 outer 更高更窄ScrollViewer
,并为其提供足够的项目以使其ListBox
本身可以滚动项目,您将看到 2 个垂直滚动条: 1 个在 theListBox
中,1 个在 the 外部ListBox
用于您的 outer ScrollViewer
。当鼠标光标位于 内部时ListBox
,ListBox
将使用其内部滚动项目ScrollViewer
,并且Border
将保持在原位。当鼠标光标在外部ListBox
和外部ScrollViewer
时,ScrollViewer
将滚动其内容 -ListBox
您可以通过注意ListBox
'Border
更改位置来验证。
如果您希望外部ScrollViewer
滚动整个ListBox
控件(包括Border
而不仅仅是项目),您需要重新设置样式以ListBox
使其没有内部ScrollViewer
,但您还需要确保它自动获取根据其项目更大。
我不推荐这种方法有几个原因。ScrollViewer
如果 内部还有其他控件可能有意义ListBox
,但您的示例并未表明这一点。此外,如果您要在 中拥有很多项目ListBox
,您将为ListBoxItem
每一个项目创建 s,从而消除默认的、非重新样式化的ListBox
由于默认而给您带来的任何优势VirtualizingStackPanel
。
请让我们知道您的实际要求是什么。
编辑:好的,现在我有了更好的主意,加上这些图像。您得到的效果是,当有足够的项目滚动并且出现滚动条时,可用区域必须水平缩小一点,因为ScrollViewer
的模板使用Grid
. 这些似乎是您的选择,按从小到大的顺序排列:
- 重新设计
ListBox
没有 aScrollViewer
并ScrollViewer
在ListBox
. 然后,您还必须强制它ListBox
也足够高以显示相同的每个项目Style
,现在您已经失去了 UI 虚拟化。如果您要在列表中显示数百个项目,您绝对不想丢失它。
- 重新设置样式
ListBox
并将其设置ControlTemplate
为使用ScrollViewer
您已经为其创建的样式,将滚动条放在内容上而不是单独的列中。这个没问题(ListBox
可以限制它的高度并使用 a VirtualizingStackPanel
,是的),但正如你所说,它需要在你的DataTemplate
.
- 重新设置样式
ScrollViewer
以便为垂直滚动条留出空间,即使它不可见。这是此选项的外观:
默认情况下,使用与此等效的ScrollViewer
2 列:Grid
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
因此,Width
当滚动条不可见时,滚动条的列为 0,因为Width="Auto"
. 为了让滚动条在隐藏时也有空间,我们Width
将该列的 绑定到Width
垂直滚动条的 :
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition
Width="{Binding ElementName=PART_VerticalScrollBar, Path=Width}" />
</Grid.ColumnDefinitions>
所以现在ControlTemplate
自定义中的Style
forScrollViewer
可能如下所示:
<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
.