繁体   English   中英

ScrollViewer 鼠标滚轮不滚动

[英]ScrollViewer mouse wheel not scrolling

我目前正在处理我的第一个 WPF 项目并尝试使ListView可滚动。 起初我认为这可以通过简单地限制ListView的宽度和高度来轻松完成,从而在内容超出其空间时强制滚动条自动出现。 起初这似乎很好,但由于处理的PreviewMouseDown事件(允许拖动列表的项目),它在选择项目后不起作用。

第二次尝试(使用ScrollViewer

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

当然,只要列表的内容大于其最大高度,就会产生第二个滚动条。 选择项目后拖动栏仍然不起作用。

第三次(相当愚蠢的)尝试(禁用滚动条重复)

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

这删除了滚动条重复并通过鼠标滚轮启用滚动但禁用了滚动条,因此您无法通过单击和拖动它来移动。

第四次尝试ScrollViewer恒定大小)

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

ListView删除宽度/高度约束并将其移动到ScrollViewer 这将启用滚动条并删除重复项。 不幸的是鼠标滚轮不再工作(拖动滚动条工作正常)。

有人可以向我解释为什么鼠标滚轮不再工作以及如何解决这个问题吗?

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

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

这可能会帮助你..

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>

对我来说这有效:

<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 Background="Transparent">

如果Background为 null,则鼠标滚轮将不会在ScrollViewer工作。 您可以将Background设置为Transparent或其他值。

就我而言,这有帮助:

<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>

该设计禁用了外部作用域中的VerticalScrollBarVisibility属性,即在ScrollViewer

我想对 Rocky 提供的解决方案添加一些评论。 它对我来说很好用,但后来我需要在不同的窗口中使用它来滚动Grid 我遇到了一个问题: 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;
}

暂无
暂无

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

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