首先,我认为您需要详细说明您的限制是什么以及您要达到的目标。没有那个,我只能解释为什么你正在做的事情不起作用。有人甚至可能对如何获得您所追求的结果有更好的想法。
如果你放在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以便为垂直滚动条留出空间,即使它不可见。这是此选项的外观:
默认情况下,使用与此等效的ScrollViewer2 列: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自定义中的StyleforScrollViewer可能如下所示:
<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.