我目前正在做我的第一个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
为空,鼠标滚轮将无法在 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;
}