在ScrollViewer中把列表框:鼠标滚轮不工作(Putting ListBox in Scro

2019-08-01 14:06发布

把一个当我的鼠标滚轮不起作用ListBoxScrollViewer

请问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大坝

Answer 1:

首先,我认为你需要详细说明你的限制是什么,以及你想达到的目标。 不这样做,我只能解释为什么你在做什么是行不通的。 有人甚至可能有关于如何得到你之后的结果更好的主意。

如果你把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 -这可以通过注意到验证ListBoxBorder改变位置。

如果你想要一个外ScrollViewer滚动整个ListBox控件(包括Border ,而不仅仅是项目),你就需要重新风格的ListBox ,使得它不会有一个内部ScrollViewer ,但你还需要确保它根据其项目自动变大。

我不推荐这种方法的一对夫妇的原因。 它可能是有意义的,如果有内部其他控件ScrollViewer与沿ListBox ,但您的样品并不表示。 另外,如果你将有很多项目的ListBox ,你就可以创建ListBoxItem的每一一个S,消除了任何优势,默认的,非重风格的ListBox让你由于默认VirtualizingStackPanel

请让我们知道您的实际需求是什么。


编辑:好,现在我有一个好一点的想法,增加这些图像。 你得到的效果是,当有足够的项目滚动并出现滚动条,可用面积必须在水平方向收缩了一下,因为ScrollViewer的模板使用一个Grid 。 这似乎是你的选择,在较小的到更好的顺序:

  1. 重新风格的ListBox不具有ScrollViewer和使用您重新风格ScrollViewer外部ListBox 。 那么你也必须强制ListBox也可以足够高,以显示在同一每一个项目Style ,现在你已经失去了UI虚拟化。 如果你要呈现出数百个在列表中的项目,你绝对不希望失去这一点。
  2. 重新风格的ListBox并设置ControlTemplate使用ScrollViewer与把滚动条在内容,而不是在一个单独的列你已经为它创建的风格。 这一个OK( ListBox得到限制其高度,并使用VirtualizingStackPanel ,耶),但正如你所说的,它需要在你的这种意识DataTemplate
  3. 重新风格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自定义StyleScrollViewer可能是这样的:

<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的滚动条的宽度,因为它得到一个一致的区域,使用滚动条是否可见或不可见。

你可能要检查出其余例子ControlTemplateScrollViewer ,但这些例子并非默认样式。 请注意,示例将垂直滚动条在左边! 还要注意,在有关底部的评论ContentScrollPresenter



Answer 2:

我正在处理同样的问题。 我设置了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>

希望这可以帮助。



Answer 3:

看到此链接的另一个答案: 在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();
        }
    }


文章来源: Putting ListBox in ScrollViewer: mouse wheel does not work