WPF DataGrid的ScrollIntoView方法在网格不在屏幕上时似乎无效

5
我有一个WPF中的DataGrid,它在TabItem中。当该网格被填充时,我希望它滚动到底部,所以我会在设置ItemsSource后对最后一个项目调用ScrollIntoView。当包含DataGrid的选项卡被选中时(网格在屏幕上),这一切都很好运行,但是如果网格不在屏幕上因为选择了其他选项卡,则ScrollIntoView无效。唯一影响ScrollIntoView是否有效的因素似乎是在调用时网格是否实际在屏幕上。这是已知的行为吗?
我尝试过调用UpdateLayout并使用Dispatcher.BeginInvoke来延迟ScrollIntoView。但这些措施都没有任何区别。
是否有一种非hacky的方法来确保如果网格在屏幕外被填充(例如选择另一个选项卡时),可以确保我可以获得所需的滚动,准备好当DataGrid被带到屏幕上时(通过选择其包含的选项卡)?我需要做一些hacky的事情,比如检测DataGrid何时可见并执行ScrollIntoView吗?

1
是的,这是WPF的默认行为,每当显示任何可视元素时,就会执行某些操作和方法。在您的情况下,由于您的数据网格选项卡尚未被选中,因此它尚未被呈现,因此您的scrollintoview将无法工作。 - Ashok Rathod
1个回答

4
发现了解决方案-与我在问题描述中所说的“hacky”的方法完全相同,但可能并不那么糟糕。发现控件有一个IsVisible属性和一个IsVisibleChanged事件。如果在我想要执行ScrollIntoViewIsVisible为false,则在我的视图类中设置一个“ScrollPending”标志;在我的IsVisibleChanged事件处理程序中,我检查IsVisible和我的ScrollPending标志是否都为true,如果是,则执行ScrollIntoView。实际上,我延迟了直到网格实际可见时才进行ScrollIntoView操作。
示例:
public partial class MyView : Control
{
    bool scrollPending;

    public MyView()
    {
        InitializeComponent();
        myDataGrid.IsVisibleChanged += myDataGrid_IsVisibleChanged;
        myDataGrid.DataContextChanged += myDataGrid_DataContextChanged;
    }

    void myDataGrid_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if (/* The list is not empty */)
        {
            if (!myDataGrid.IsVisible)
            {
                scrollPending = true;
            }
            else
            {
                myDataGrid.ScrollIntoView(/* The last item in the list */);
                scrollPending = false;
            }
        }
        else
        {
            scrollPending = false;
        }
    }

    void myDataGrid_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if (scrollPending && myDataGrid.IsVisible /* && list is not empty */ )
        {
            myDataGrid.ScrollIntoView(/* The last item in the list */);
            scrollPending = false;
        }
    }
}

谢谢,这帮了我很大的忙。我一度感到非常无助。 - Jake Gaston

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