首先,我认为你需要详细说明你的限制是什么,以及你想达到的目标。没有这个,我只能解释你为什么做不到。有人甚至可以更好地了解如何获得后续结果。
如果你把一个ListBox
里面ScrollViewer
,那么control template为ListBox
仍然有它自己的内部ScrollViewer
。当鼠标光标位于ListBox
上方,并且滚动鼠标滚轮时,该事件会冒泡,直至到达ListBox
的ScrollViewer
。那个人通过滚动来处理它,并将事件标记为已处理,所以ScrollViewer
你把ListBox
忽略了事件。在ListBox
1和1之外:
如果使ListBox
比外ScrollViewer
更高和更窄,并给予足够的项目,以便ListBox
本身可以滚动的物品,你会看到2垂直滚动条ListBox
为您的外ScrollViewer
。当鼠标光标位于ListBox
内部时,ListBox
将滚动其内部ScrollViewer
的项目,其Border
将保持原位。当鼠标光标在ListBox
之外,并在外部ScrollViewer
之内时,该ScrollViewer
将滚动其内容 - ListBox
- 您可以通过注意ListBox
的Border
更改位置来验证。
如果你想要一个外ScrollViewer
滚动整个ListBox
控制(包括Border
,而不仅仅是项目),你就需要重新风格ListBox
因此它不具有内部ScrollViewer
,但你”还需要确保它根据其物品自动变大。
我不建议这种方法,由于几个原因。如果ScrollViewer
以及ListBox
内有其他控件,但您的示例并未指出该示例,则可能有意义。此外,如果您要在ListBox
中拥有大量商品,那么您将为每一个商品创建ListBoxItem
s,从而消除由于默认VirtualizingStackPanel
而导致的默认非重新设计ListBox
的优势。
请让我们知道您的实际要求是什么。
编辑:好了,现在我有一个好一点的想法,增加这些图像。你得到的效果是,当有足够的项目滚动和滚动条出现时,可用区域必须水平缩小一点,因为ScrollViewer
的模板使用Grid
。这似乎是你的选择,在较小的到更好的顺序:
- 重新风格
ListBox
到没有ScrollViewer
和使用您重新风格ScrollViewer
的ListBox
之外。然后,您还必须强制ListBox
也足够高,以显示相同的Style
中的每个项目,现在您已经失去了UI虚拟化。如果你打算在列表中显示数百个项目,那么你的肯定是不想失去它。
- 重新设计
ListBox
,并将ControlTemplate
设置为使用ScrollViewer
,该样式为您为其创建的样式将滚动条放在内容上而不是单独列中。这是一个好的(ListBox
得到限制其高度,并使用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>
所以现在在定制Style
为ScrollViewer
可能是这样的ControlTemplate
:
<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
不必为滚动条的宽度进行补偿,因为无论滚动条是否可见,它都会使用一致的区域。
您可能需要查看example ControlTemplate
for ScrollViewer
的其余部分,但这些示例不是默认样式。 请注意,该示例将垂直滚动条放在左侧!另请注意关于ContentScrollPresenter
底部的评论。
更新了我的帖子.. – 2009-08-19 07:33:56