我在 TabItem 中有一个WPF DataGrid 。填充网格后,我希望它滚动到底部,所以在设置 ItemsSource 后,我在最后一个项目上调用 ScrollIntoView 。当选择包含 DataGrid 的选项卡(网格在屏幕上)时,这一切都正常,但如果网格不在屏幕上,因为选择了其他选项卡, ScrollIntoView 什么都不做。似乎影响 ScrollIntoView 是否能完成工作的唯一因素是网格是否在呼叫时实际显示在屏幕上。这是一种已知行为吗?
我尝试调用UpdateLayout并使用Dispatcher.BeginInvoke来推迟ScrollIntoView。这些措施都没有任何区别。
是否有一种非黑客的方法来确保如果在屏幕外填充网格(如选择另一个选项卡),则可以确保我可以获得所需的滚动,准备好 DataGrid 会显示在屏幕上(通过选择其包含的标签)?当 DataGrid 变得可见并执行 ScrollIntoView 时,我是否需要做一些像hacky这样的事情?
答案 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;
}
}
}