简体   繁体   English

ScrollViewer 鼠标滚轮不滚动

[英]ScrollViewer mouse wheel not scrolling

I am currently working on my first WPF project and trying to make a ListView scrollable.我目前正在处理我的第一个 WPF 项目并尝试使ListView可滚动。 At first I thought this could be easily done by simply limiting the ListView 's width and height and thus forcing a scrollbar to appear automatically whenever the content exceeds its space.起初我认为这可以通过简单地限制ListView的宽度和高度来轻松完成,从而在内容超出其空间时强制滚动条自动出现。 This seemed fine at first but due to the handled PreviewMouseDown event (which enables dragging the list's items) it doesn't work after selecting an item.起初这似乎很好,但由于处理的PreviewMouseDown事件(允许拖动列表的项目),它在选择项目后不起作用。

Second attempt (using ScrollViewer )第二次尝试(使用ScrollViewer

<ScrollViewer>
    <ListView ItemsSource="{Binding FileViewModels}"
              PreviewMouseDown="ListView_MouseMove"
              Height="450" Width="200"/>
</ScrollViewer>

Of course, this resulted in a second scrollbar whenever the list's content became larger than its max height.当然,只要列表的内容大于其最大高度,就会产生第二个滚动条。 And dragging the bar still didn't work after selecting an item.选择项目后拖动栏仍然不起作用。

Third (quite foolish) attempt (disabling scrollbar duplicate)第三次(相当愚蠢的)尝试(禁用滚动条重复)

<ScrollViewer>
    <ListView ItemsSource="{Binding FileViewModels}"
              PreviewMouseDown="ListView_MouseMove"
              Height="450" Width="200"
              ScrollViewer.VerticalScrollBarVisibility="Disabled"
              ScrollViewer.HorizontalScrollBarVisibility="Disabled"/>
</ScrollViewer>

This removed the scrollbar duplicate and enabled scrolling via mouse wheel but disabled the scrollbar, so you couldn't move by clicking and dragging it.这删除了滚动条重复并通过鼠标滚轮启用滚动但禁用了滚动条,因此您无法通过单击和拖动它来移动。

Fourth attempt (constant size of the ScrollViewer )第四次尝试ScrollViewer恒定大小)

<ScrollViewer Height="450" Width="200">
    <ListView ItemsSource="{Binding FileViewModels}"
              PreviewMouseDown="ListView_MouseMove"/>
</ScrollViewer>

Removed the width/height constraint from the ListView and moved it to the ScrollViewer .ListView删除宽度/高度约束并将其移动到ScrollViewer This enables the scrollbar and removes the duplicate.这将启用滚动条并删除重复项。 Unfortunately the mouse wheel doesn't work anymore (dragging the scroll bar works fine).不幸的是鼠标滚轮不再工作(拖动滚动条工作正常)。

Could somebody please explain to me why the mouse wheel doesn't work anymore and how to fix this?有人可以向我解释为什么鼠标滚轮不再工作以及如何解决这个问题吗?

Edit Maybe I should go back to my first solution.编辑也许我应该回到我的第一个解决方案。

Obviously, the ListView 's template already contains a ScrollViewer .显然, ListView的模板已经包含一个ScrollViewer The remaining problem would then be that I cannot drag the scrollbar after selecting an item because of the handled PreviewMouseDown event (scrolling via MouseWheel still works in that case).剩下的问题是,由于处理的PreviewMouseDown事件(在这种情况下,通过 MouseWheel 滚动仍然有效),我无法在选择项目后拖动滚动条。 Should I handle the dragging of items differently (it worked fine for me, before wanting to add a scrollbar)?我是否应该以不同的方式处理项目的拖动(在想要添加滚动条之前,它对我来说很好用)? Or is there a way to detect if the cursor is above the scrollbar (so I could then deselect the item which enables scrolling)?或者有没有办法检测光标是否在滚动条上方(这样我就可以取消选择启用滚动的项目)? Or are there any other suggestions?或者还有其他建议吗?

This may help you..这可能会帮助你..

private void ListViewScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
   ScrollViewer scv = (ScrollViewer)sender;
   scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
   e.Handled = true;
 }

This would probably be the most comfortable solution:这可能是最舒适的解决方案:

<ListView.Template>
    <ControlTemplate>
        <ScrollViewer>
            <ItemsPresenter></ItemsPresenter> 
        </ScrollViewer>
    </ControlTemplate>
</ListView.Template>

For me this worked:对我来说这有效:

<ListView.Template>
    <ControlTemplate>
        <!-- Empty template to allow ScrollViewer to capture mouse scroll -->
        <ItemsPresenter />
    </ControlTemplate>
</ListView.Template>

instead of this:而不是这个:

<ListView.Template>
    <ControlTemplate>
        <ScrollViewer>
            <ItemsPresenter></ItemsPresenter>
        </ScrollViewer>
    </ControlTemplate>
</ListView.Template>
<ScrollViewer Background="Transparent">

If Background is null, the mouse wheel will not work on ScrollViewer .如果Background为 null,则鼠标滚轮将不会在ScrollViewer工作。 You can set the Background to Transparent or some other value.您可以将Background设置为Transparent或其他值。

In my case this helped:就我而言,这有帮助:

<ScrollViewer ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Auto" >
    <DataGrid x:Name="dataGrid" SelectionMode="Single" ItemsSource="{Binding}"  SelectedValuePath="{Binding Item}" AutoGenerateColumns="True">
    </DataGrid>
</ScrollViewer>

The design was disabling VerticalScrollBarVisibility attribute in outer scope , ie in ScrollViewer .该设计禁用了外部作用域中的VerticalScrollBarVisibility属性,即在ScrollViewer

I want to add some comment to the solution Rocky provided.我想对 Rocky 提供的解决方案添加一些评论。 It worked fine for me, but later I needed to use it in a different window to scroll Grid .它对我来说很好用,但后来我需要在不同的窗口中使用它来滚动Grid I faced a problem: the ScrollViewer did not scroll to the bottom end.我遇到了一个问题: ScrollViewer没有滚动到底部。 The reason was because of attempts to set the invalid VerticalOffset value.原因是因为尝试设置无效的VerticalOffset值。 The code below works fine for me (just need to change PreviewMouseWheel handler:下面的代码对我来说很好用(只需要更改PreviewMouseWheel处理程序:

private void UIElement_OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    ScrollViewer scroll = (ScrollViewer)sender;
    if (e.Delta < 0)
    {
        if (scroll.VerticalOffset - e.Delta <= scroll.ExtentHeight - scroll.ViewportHeight)
        {
            scroll.ScrollToVerticalOffset(scroll.VerticalOffset - e.Delta);
        }
        else
        {
            scroll.ScrollToBottom();
        }
    }
    else
    {
        if (scroll.VerticalOffset + e.Delta > 0)
        {
            scroll.ScrollToVerticalOffset(scroll.VerticalOffset - e.Delta);
        }
        else
        {
            scroll.ScrollToTop();
        }
    }
    e.Handled = true;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM