我在Silverlight应用程序中使用DataGrid来显示一些在计时器上刷新的数据。我的问题是,当发生这种情况时,网格中的垂直滚动条重置到顶部,而我希望它保持在相同的位置。有谁知道我怎么能做到这一点?
我已尝试覆盖网格上的ItemsSource属性以存储垂直滚动位置然后重置它,但这只会影响滚动条并且不会强制显示正确的行。有没有办法强迫这种行为?
答案 0 :(得分:2)
以下是关于在ListBox上设置滚动条位置的类似问题
After rebinding Silverlight Listbox control how do you get it listbox to scroll to back to the top?
由于DataGrid还支持ScrollIntoView方法,因此您应该能够使用类似的技术,例如
theDataGrid.ItemsSource = data;
theDataGrid.UpdateLayout();
theDataGrid.ScrollIntoView(theDataGrid.SelectedItem, theDataGrid.Columns[0]);
答案 1 :(得分:1)
上次看的时候,我找不到合适的答案。我想保持在网格中选择当前元素,但这不适用于ICollectionView
刷新(我使用MVVM并从服务器获取自动更新)。
ScrollIntoView()
对我来说不是一个选项,因为当前所选的项目可能不在视图中。让CurrentChanged
事件失控也很麻烦。
最后,我使用了Infragistics网格,它开箱即用。问题解决了我。
您可以查看DevExpress免费网格。我认为它具有相同的好行为(我测试了它,但我不记得结果)。
答案 2 :(得分:0)
您可以尝试在UI线程中设置SelectedItem,以便UI可以刷新自身, 像这样
private void Button_Click(object sender, RoutedEventArgs e)
{
Person p = new Person() { Name="sss",Age=11}; //datagird's itemsSource is Collection<person>
people.Add(p);
dg.SelectedItem = p; //dg is my datagrid name
Dispatcher.BeginInvoke(() => { dg.SelectedItem = p; });
}
我假设在ViewModel中加载了新行,这就是为什么将BeginInvoke放在那里是有意义的。由于ViewModel操作在不同的线程上运行,并且只是单独设置SelectedItem可能不起作用,这适用于someone else
答案 3 :(得分:0)
我也遇到过这个问题。我通过记住要滚动到的项目,然后重新绑定DataGrid来解决它。我处理LayoutUpdated事件以实现所需的功能:
void MyDataGrid_LayoutUpdated(object sender, EventArgs e)
{
// Reference the data item in the list you want to scroll to.
object dataItem = yourDataItem;
// Make sure the item is not null and didn't already scroll to the item.
if (dataItem != null && this.dataItemScrolledTo != dataItem)
{
// Remember the item scrolled to.
this.dataItemScrolledTo = dataItem;
// Scroll datagrid to the desired item.
MyDataGrid.ScrollIntoView(dataItem, MyDataGrid.Columns[0]);
}
}
答案 4 :(得分:0)
我修改了CodeMaster的解决方案,因此您不需要类级变量。将此代码放在更新ItemsSource的方法中。它将动态创建事件处理程序,附加它,然后将其分离。
EventHandler MyDataGrid_LayoutUpdated = null;
MyDataGrid_LayoutUpdated = (s, e) =>
{
MyDataGrid.ScrollIntoView(dataItem, MyDataGrid.Columns[0]);
MyDataGrid.LayoutUpdated -= MyDataGrid_LayoutUpdated;
};
MyDataGrid.LayoutUpdated += MyDataGrid_LayoutUpdated;