我有一个充满笔记的DataGrid,有可能一条笔记的高度超过了DataGrid的高度。当这种情况发生时,如果您尝试向下滚动以阅读笔记的下半部分,则DataGrid会立即跳到下一行。
这不仅阻止用户查看完整的笔记,而且还会导致滚动感觉很不流畅,因为它似乎会跳来跳去。
有没有办法告诉WPF在不禁用默认的DataGrid虚拟化的情况下顺畅地滚动长笔记?
我相信你正在寻找可以在DataGrid上设置的VirtualizingPanel.ScrollUnit
附加属性。
如果将其值设置为Pixel
,而不是默认值Item
,那么它应该可以实现你想要的效果。
如果你不想升级到.NET 4.5,你仍然可以在基础的VirtualizingStackPanel上设置IsPixelBased属性。不过,在.NET 4.0中,这个属性是内部的,因此你需要通过反射来设置它。
public static class VirtualizingStackPanelBehaviors
{
public static bool GetIsPixelBasedScrolling(DependencyObject obj)
{
return (bool)obj.GetValue(IsPixelBasedScrollingProperty);
}
public static void SetIsPixelBasedScrolling(DependencyObject obj, bool value)
{
obj.SetValue(IsPixelBasedScrollingProperty, value);
}
// Using a DependencyProperty as the backing store for IsPixelBasedScrolling. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsPixelBasedScrollingProperty =
DependencyProperty.RegisterAttached("IsPixelBasedScrolling", typeof(bool), typeof(VirtualizingStackPanelBehaviors), new UIPropertyMetadata(false, OnIsPixelBasedScrollingChanged));
private static void OnIsPixelBasedScrollingChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var virtualizingStackPanel = o as VirtualizingStackPanel;
if (virtualizingStackPanel == null)
throw new InvalidOperationException();
var isPixelBasedPropertyInfo = typeof(VirtualizingStackPanel).GetProperty("IsPixelBased", BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.NonPublic);
if (isPixelBasedPropertyInfo == null)
throw new InvalidOperationException();
isPixelBasedPropertyInfo.SetValue(virtualizingStackPanel, (bool)(e.NewValue), null);
}
}
在你的 XAML 中:
<DataGrid>
<DataGrid.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" local:VirtualizingStackPanelBehaviors.IsPixelBasedScrolling="True" />
</ItemsPanelTemplate>
</DataGrid.ItemsPanel>
</DataGrid>
ScrollViewer
中,然后将其MaxHeight
设置为 DataGrid 的高度? - McGarnagleCanContentScroll
属性设置为False
吗? - Rohit VatsCanContentScroll
将会将滚动设置为 false 并禁用虚拟化。 - Rachel