c# – 将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>

编辑:按照乔尔的要求,添加了我这样做的原因..
我这样做是因为我不喜欢ListBox的内部ScrollViewer对我的布局所做的事情.我有一个背景图片,最重要的是ListBox,如下所示:

alt text http://robbertdam.nl/share/1.png

现在,当滚动条出现时,会发生以下情况:

alt text http://robbertdam.nl/share/2.png

我为ScrollViewer创建了一个Style,它在ListBox项目的内容之上显示滚动条.在ListBox项的datatemplate中,我为滚动条保留了一些空间.

谢谢,
罗伯特大坝

解决方法

首先,我认为你需要详细说明你的局限性以及你想要实现的目标.没有它,我只能解释为什么你所做的不起作用.有人甚至可能对如何获得你想要的结果有更好的了解.

如果将ListBox放在ScrollViewer中,那么control template for ListBox内部仍然有自己的ScrollViewer.当鼠标光标位于ListBox上并滚动鼠标滚轮时,该事件会一直冒泡,直到它到达属于ListBox的ScrollViewer.那个人通过滚动处理它并将事件标记为已处理,因此将ListBox放入其中的ScrollViewer忽略该事件.

如果你使ListBox比外部ScrollViewer更高更窄,并给它足够的项目以便ListBox本身可以滚动项目,你会看到2个垂直滚动条:ListBox中有1个,外部有ListBox外有1个ScrollViewer中.当鼠标光标位于ListBox内部时,ListBox将使用其内部ScrollViewer滚动项目,其边框将保持不变.当鼠标光标位于ListBox外部并位于外部ScrollViewer内部时,ScrollViewer将滚动其内容 – ListBox – 您可以通过注意ListBox的Border更改位置来验证它.

如果你想让一个外部的ScrollViewer滚动整个ListBox控件(包括Border而不仅仅是项目),你需要重新设置ListBox的样式,使它没有内部的ScrollViewer,但是你还需要确保它根据其项目自动变大.

出于某些原因,我不推荐这种方法.如果ScrollViewer中有其他控件和ListBox,则可能有意义,但您的示例并未指出.此外,如果您要在ListBox中拥有大量项目,那么您将为每一个项目创建ListBoxItems,从而消除了由于认的VirtualizingStackPanel而认的,非重新设置样式的ListBox为您提供的任何优势.

请告诉我们您的实际要求.

编辑:好的,现在我有一个更好的主意,添加了这些图像.您得到的效果是,当有足够的项目滚动并且滚动条出现时,可用区域必须水平缩小一点,因为ScrollViewer的模板使用网格.这些似乎是你的选择,按顺序越来越好:

>将ListBox重新设置为没有ScrollViewer,并在ListBox外部使用重新设置样式的ScrollViewer.然后,您还必须强制ListBox也足够高,以显示相同样式中的每个项目,现在您已经失去了UI虚拟化.如果您要在列表中显示数百个项目,那么您绝对不想失去它.
>重新设置ListBox的样式,并将ControlTemplate设置为使用ScrollViewer,该ScrollViewer具有您为其创建的样式,将滚动条放在内容上而不是单独的列中.这个没问题(ListBox可以限制它的高度并使用VirtualizingStackPanel,但是正如你所说,它需要在你的DataTemplate中意识到这一点.
>重新设置ScrollViewer的样式,为垂直滚动条留出空间,即使它不可见.这是这个选项的样子:

认情况下,ScrollViewer在Grid中使用2个等效于此的列:

<Grid.ColumnDeFinitions>
    <ColumnDeFinition Width="*" />
    <ColumnDeFinition Width="Auto" />
</Grid.ColumnDeFinitions>

因此当滚动条不可见时,滚动条列的宽度为0,因为Width =“Auto”.要为滚动条留出空间,即使它被隐藏,我们也会将该列的宽度绑定到垂直滚动条的宽度:

<Grid.ColumnDeFinitions>
    <ColumnDeFinition Width="*" />
    <ColumnDeFinition
        Width="{Binding ElementName=PART_VerticalScrollBar,Path=Width}" />
</Grid.ColumnDeFinitions>

所以现在ScrollViewer的自定义Style中的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的评论.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...