把一个当我的鼠标滚轮不起作用ListBox
的ScrollViewer
。
请问ListBox
有点“偷”这个活动?
<ScrollViewer VerticalScrollBarVisibility="Auto" Style="{StaticResource myStyle}">
<ListBox>
<ListBoxItem>Test 1</ListBoxItem>
<ListBoxItem>Test 2</ListBoxItem>
<ListBoxItem>Test 3</ListBoxItem>
<ListBoxItem>Test 4</ListBoxItem>
<ListBoxItem>Test 5</ListBoxItem>
<ListBoxItem>Test 6</ListBoxItem>
<ListBoxItem>Test 7</ListBoxItem>
</ListBox>
</ScrollViewer>
编辑:乔尔的要求,加入我为什么这样做的原因。我这样做是因为我不喜欢什么, ListBox
的内部ScrollViewer
与我的布局。 我有一个背景图像,以及一个顶部ListBox
,如下所示:
替代文字http://robbertdam.nl/share/1.png
滚动条上出现现在的情况下,会发生以下情况:
替代文字http://robbertdam.nl/share/2.png
我创建了一个样式ScrollViewer
,显示在顶部的滚动条ListBox
项目的内容。 在ListBox
项的DataTemplate中我为你保留的滚动条出现一些空间。
谢谢,Robbert大坝
首先,我认为你需要详细说明你的限制是什么,以及你想达到的目标。 不这样做,我只能解释为什么你在做什么是行不通的。 有人甚至可能有关于如何得到你之后的结果更好的主意。
如果你把ListBox
一个内部ScrollViewer
,那么控制模板的ListBox
仍然有它自己ScrollViewer
内。 当鼠标光标在ListBox
和滚动鼠标滚轮,该事件气泡,直到它到达ScrollViewer
这部分ListBox
。 那一个滚动处理它标志着事件的处理,所以随后ScrollViewer
你把ListBox
里面忽略该事件。
如果您的ListBox
比外高和窄ScrollViewer
,并给它足够的项目,以便在ListBox
本身可以滚动的物品,你会看到2个垂直滚动条:在1 ListBox
,和1个外部ListBox
为您的外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
不具有ScrollViewer
和使用您重新风格ScrollViewer
外部ListBox
。 那么你也必须强制ListBox
也可以足够高,以显示在同一每一个项目Style
,现在你已经失去了UI虚拟化。 如果你要呈现出数百个在列表中的项目,你绝对不希望失去这一点。 - 重新风格的
ListBox
并设置ControlTemplate
使用ScrollViewer
与把滚动条在内容,而不是在一个单独的列你已经为它创建的风格。 这一个OK( 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>
所以现在ControlTemplate
自定义Style
的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
不必compenstate的滚动条的宽度,因为它得到一个一致的区域,使用滚动条是否可见或不可见。
你可能要检查出其余例子ControlTemplate
的ScrollViewer
,但这些例子并非默认样式。 请注意,示例将垂直滚动条在左边! 还要注意,在有关底部的评论ContentScrollPresenter
。
我正在处理同样的问题。 我设置了ListBox.ItemsPanel属性,没有任何的ScrollViewer:
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ListBox>
<ListBox.Template>
<ControlTemplate TargetType="ItemsControl">
<Border>
<ItemsPresenter />
</Border>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<\ListBox>
<\ScrollViewer>
希望这可以帮助。
看到此链接的另一个答案: 在ScrollViewer中滚动,当鼠标移到列表框
你好,我想你可以处理整个ListBox的PreviewMouseWheel事件。 这也将只要你不处理影响单个项目的每个项目的
PreviewMouseWheel and mark the event as handled:
private void ListBox_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta < 0)
{
scrollViewer1.LineDown();
}
else
{
scrollViewer1.LineUp();
}
}