C# ScrollViewer鼠标滚轮不滚动

C# ScrollViewer鼠标滚轮不滚动,c#,wpf,xaml,scrollviewer,mousewheel,C#,Wpf,Xaml,Scrollviewer,Mousewheel,我目前正在进行我的第一个WPF项目,并试图使列表视图可滚动。 起初,我认为这可以通过简单地限制列表视图的宽度和高度,从而在内容超出其空间时强制自动显示滚动条来实现。起初这看起来不错,但由于处理了PreviewMouseDown事件(该事件允许拖动列表的项目),因此在选择项目后它不起作用 第二次尝试(使用ScrollViewer) 从列表视图中删除了宽度/高度约束,并将其移动到滚动查看器。这将启用滚动条并删除重复项。不幸的是,鼠标滚轮不再工作(拖动滚动条工作正常) 有人能给我解释一下为什么鼠标滚轮

我目前正在进行我的第一个WPF项目,并试图使
列表视图可滚动。
起初,我认为这可以通过简单地限制
列表视图的宽度和高度,从而在内容超出其空间时强制自动显示滚动条来实现。起初这看起来不错,但由于处理了
PreviewMouseDown
事件(该事件允许拖动列表的项目),因此在选择项目后它不起作用

第二次尝试(使用
ScrollViewer

列表视图中删除了宽度/高度约束
,并将其移动到
滚动查看器
。这将启用滚动条并删除重复项。不幸的是,鼠标滚轮不再工作(拖动滚动条工作正常)

有人能给我解释一下为什么鼠标滚轮不再工作了,以及如何解决这个问题吗

编辑 也许我应该回到我的第一个解决方案。

显然,
ListView
的模板已经包含了一个
ScrollViewer
。剩下的问题是,由于已处理的
PreviewMouseDown
事件(在这种情况下,通过鼠标滚轮滚动仍然有效),我无法在选择项目后拖动滚动条。我是否应该以不同的方式处理项目的拖动(在想要添加滚动条之前,这对我来说很好)?或者有没有办法检测光标是否在滚动条上方(这样我就可以取消选择启用滚动的项目)? 或者还有其他建议吗?

这可能会对您有所帮助

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

这可能是最舒适的解决方案:

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



如果
Background
为空,鼠标滚轮将无法在
ScrollViewer
上工作。您可以将
背景设置为
透明
或其他值。

在我的例子中,这有助于:


设计在外部范围禁用了
VerticalScrollBarVisibility
属性,即在
ScrollViewer

中,对我来说,这起到了作用:

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

与此相反:

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

我想对提供的解决方案添加一些注释。它对我来说很好,但后来我需要在另一个窗口中使用它来滚动
网格
。我遇到了一个问题:
ScrollViewer
没有滚动到底部。原因是试图设置无效的
VerticalOffset
值。下面的代码对我来说很好(只需更改
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;
}
PreviewMouseWheel(对象发送者,MouseWheelEventArgs e)上的私有void ui元素 { ScrollViewer scroll=(ScrollViewer)发送方; 如果(e.Delta<0) { 如果(滚动垂直偏移-e.增量0) { scroll.ScrollToVerticalOffset(scroll.VerticalOffset-e.Delta); } 其他的 { scroll.ScrollToTop(); } } e、 已处理=正确; }
Nice,这很有效-谢谢。但我仍然不确定在ScrollViewer中使用ListView是否是一种好的样式(请参见上面的编辑部分)。我发现将
e.Delta
除以10可以使滚动的粒度更细(不太粗)。(不过回答得不错!)最佳解决方案。可能会将Itemspresenter放入
网格
DockPanel
我面临一个小问题,您的解决方案..标题现在消失..有什么建议吗?@shalvinaham什么标题?Listview没有我知道的标题?我对WPF不熟悉,所以可能是我的误解..我使用Listview的目的是:带标题。我可以通过添加此选项来解决问题,如果鼠标指针位于滚动条上方,则此选项仅适用于我,但如果鼠标指针位于内容上方,则此选项不适用。这应该是公认的答案。此选项有效且简单。谢谢!同意。这是唯一的答案这对我有用!谢谢!
<ScrollViewer Background="Transparent">
<ListView.Template>
    <ControlTemplate>
        <!-- Empty template to allow ScrollViewer to capture mouse scroll -->
        <ItemsPresenter />
    </ControlTemplate>
</ListView.Template>
<ListView.Template>
    <ControlTemplate>
        <ScrollViewer>
            <ItemsPresenter></ItemsPresenter>
        </ScrollViewer>
    </ControlTemplate>
</ListView.Template>
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;
}