当行高大于视口时,我该如何使DataGrid平稳滚动?

10

我有一个充满笔记的DataGrid,有可能一条笔记的高度超过了DataGrid的高度。当这种情况发生时,如果您尝试向下滚动以阅读笔记的下半部分,则DataGrid会立即跳到下一行。

这不仅阻止用户查看完整的笔记,而且还会导致滚动感觉很不流畅,因为它似乎会跳来跳去。

有没有办法告诉WPF在不禁用默认的DataGrid虚拟化的情况下顺畅地滚动长笔记?


你能否将该注释放入一个 ScrollViewer 中,然后将其 MaxHeight 设置为 DataGrid 的高度? - McGarnagle
1
@dbaseman 我希望表头始终可见,并且这将禁用DataGrid的虚拟化,因为它会呈现所有项。 - Rachel
你尝试过将DataGrid的ScrollViewer的CanContentScroll属性设置为False吗? - Rohit Vats
@RV1987 为什么要这样做呢?我想要滚动行为,但是我希望它可以平稳地滚动大型项目,而不是一次滚动一个项目。设置 CanContentScroll 将会将滚动设置为 false 并禁用虚拟化。 - Rachel
你看过这个链接吗:https://dev59.com/jnA75IYBdhLWcg3w3NHf - Jason Massey
2个回答

27

我相信你正在寻找可以在DataGrid上设置的VirtualizingPanel.ScrollUnit附加属性。

如果将其值设置为Pixel,而不是默认值Item,那么它应该可以实现你想要的效果。


很不幸,我正在使用 .Net 4.0,但如果没有其他简单的解决方案,我可以考虑升级我正在使用的 .Net 框架版本。谢谢。 - Rachel

2

如果你不想升级到.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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接