我在TabItem中有一个 WPF DataGrid。填充网格后,我希望它滚动到底部,因此我在设置ItemsSource后对最后一个项目调用ScrollIntoView。当选择包含DataGrid的选项卡(网格在屏幕上)时,这一切都可以正常工作,但如果由于选择了其他选项卡而导致网格不在屏幕上,则ScrollIntoView不会执行任何操作。影响ScrollIntoView是否完成其工作的唯一因素似乎是网格在调用时是否实际在屏幕上。这是已知行为吗?
我尝试调用 UpdateLayout 并使用 Dispatcher.BeginInvoke 来推迟 ScrollIntoView。这些措施都没有任何作用。
是否有一种非 hacky 的方法来确保如果在屏幕外填充网格(如选择另一个选项卡时),则可以确保我可以获得所需的滚动,为 DataGrid 出现在屏幕上时做好准备(例如通过选择其包含选项卡)?我是否需要做一些像检测DataGrid何时可见并执行ScrollIntoView 之类的事情?
找到了解决方案 - 正是我在问题中所描述的“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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1552 次 |
| 最近记录: |