Rob*_*Dam 8 c# wpf xaml listbox scrollviewer
把一个当我的鼠标滚轮不起作用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>
Run Code Online (Sandbox Code Playgroud)
编辑:按照Joel的要求,添加了我之所以这样做的原因..我这样做是因为我不喜欢ListBox
内部ScrollViewer
对我的布局做了什么.我有一个背景图片,除此之外,ListBox
如下图所示:
替代文字http://robbertdam.nl/share/1.png
现在,当滚动条出现时,会发生以下情况:
替代文字http://robbertdam.nl/share/2.png
我创建了一个样式ScrollViewer
,显示滚动条顶部的的ListBox
项目内容.在ListBox
项目的datatemplate中,我为滚动条保留了一些空间.
谢谢,Robbert Dam
Joe*_*ant 15
首先,我认为你需要详细说明你的局限性以及你想要实现的目标.没有它,我只能解释为什么你所做的不起作用.有人甚至可能对如何获得你想要的结果有更好的了解.
如果你把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
已为其创建的样式,将滚动条放在内容上而不是单独的列中.这一个是好的(ListBox
限制它的高度并使用a VirtualizingStackPanel
,yay),但正如你所说,它需要你的意识DataTemplate
.ScrollViewer
为垂直滚动条留出空间,即使它不可见.这是这个选项的样子:默认情况下,ScrollViewer
使用Grid
等效于此的2列:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
Run Code Online (Sandbox Code Playgroud)
因此,Width
当滚动条不可见时,滚动条列的列为0 Width="Auto"
.要为滚动条留出空间,即使它被隐藏,我们也会Width
将该列绑定到Width
垂直滚动条:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition
Width="{Binding ElementName=PART_VerticalScrollBar, Path=Width}" />
</Grid.ColumnDefinitions>
Run Code Online (Sandbox Code Playgroud)
所以现在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>
Run Code Online (Sandbox Code Playgroud)
您甚至可以将内容列设置为固定大小和滚动条列Width="*"
,如果图像未拉伸,则可能会在长时间内更好地工作.现在,DataTemplate
不必为滚动条的宽度进行补偿,因为无论滚动条是否可见,它都可以使用一致的区域.
你可能要检查出其余例子ControlTemplate
为ScrollViewer
,但这些例子并非默认样式.请注意,该示例将垂直滚动条放在左侧!另请注意底部的评论ContentScrollPresenter
.
小智 7
我正在处理同一个问题。我设置了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>
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助。