如果网格不在屏幕上,WPF DataGrid ScrollIntoView显然不会执行任何操作

时间:2015-02-03 03:00:08

标签: c# wpf datagrid

我在 TabItem 中有一个WPF DataGrid 。填充网格后,我希望它滚动到底部,所以在设置 ItemsSource 后,我在最后一个项目上调用 ScrollIntoView 。当选择包含 DataGrid 的选项卡(网格在屏幕上)时,这一切都正常,但如果网格不在屏幕上,因为选择了其他选项卡, ScrollIntoView 什么都不做。似乎影响 ScrollIntoView 是否能完成工作的唯一因素是网格是否在呼叫时实际显示在屏幕上。这是一种已知行为吗?

我尝试调用UpdateLayout并使用Dispatcher.BeginInvoke来推迟ScrollIntoView。这些措施都没有任何区别。

是否有一种非黑客的方法来确保如果在屏幕外填充网格(如选择另一个选项卡),则可以确保我可以获得所需的滚动,准备好 DataGrid 会显示在屏幕上(通过选择其包含的标签)?当 DataGrid 变得可见并执行 ScrollIntoView 时,我是否需要做一些像hacky这样的事情?

1 个答案:

答案 0 :(得分:2)

找到了解决方案 - 正是我在我的问题中所描述的“hacky”,但也许并不那么糟糕。发现控件具有 IsVisible 属性和 IsVisibleChanged 事件。如果我想执行 ScrollIntoView IsVisible 为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;
        }
    }
}