我有带过滤器的datagrid(列之一是时间)。在使用过滤器之前,用户可以向下滚动至时间,例如2:00 pm
使用过滤器后,datagrid中显示的第一行必须为2:00 pm(将假定此行始终存在)
我有两种方法:
1.重置datagrid itemsSource之前先调用
Statistics.ScrollPositionData GetScrollPosition()
{
try
{
if (VisualTreeHelper.GetChildrenCount(dg_timing) > 0)
{
var border = VisualTreeHelper.GetChild(dg_timing, 0) as Decorator;
if (border != null)
{
var scroll = border.Child as ScrollViewer;
if (scroll != null)
{
var view = CollectionViewSource.GetDefaultView(dg_timing.ItemsSource) as CollectionView;
DataRowView firstItem = view.GetItemAt((int)scroll.VerticalOffset) as DataRowView; //here is incorrect code
return new Statistics.ScrollPositionData()
{
offset = scroll.VerticalOffset,
rowId = (firstItem.Row.ItemArray[((Statistics)DataContext).GetColumnOrder("Timeline")] as TextBlock).Text
};
}
}
}
}
catch (Exception) { }
return null;
}
重置数据网格项后调用源
void SetScrollPosition(Statistics.ScrollPositionData offset)
{
try
{
if (offset != null)
{
var t1 = (CollectionViewSource.GetDefaultView(dg_timing.ItemsSource) as CollectionView);
var t2 = t1.Cast<DataRowView>();
var row = t2.
LastOrDefault(w =>
{
string t = (w.Row.ItemArray[((Statistics)DataContext).GetColumnOrder("Timeline")] as TextBlock).Text;
long l1 = DateTime.ParseExact(t, @"mm\:ss\:ff", CultureInfo.InvariantCulture).Ticks;
long l2 = DateTime.ParseExact(offset.rowId, @"mm\:ss\:ff", CultureInfo.InvariantCulture).Ticks;
return t == offset.rowId || l1 < l2;
});
var border = VisualTreeHelper.GetChild(dg_timing, 0) as Decorator;
if (border != null)
{
var scroll = border.Child as ScrollViewer;
if (scroll != null)
{
scroll.ScrollToBottom();
if (row != null)
{
dg_timing.SelectedItem = row;
dg_timing.ScrollIntoView(row);
}
else
{
scroll.ScrollToVerticalOffset(offset.offset);
}
}
}
}
}
catch (Exception) { }
}
问题在于在datagrid中找到第一条显示行
P.S。感谢@habib提供文本编辑帮助
答案 0 :(得分:0)
我想我已经找到了完整的解释HowTo和列表视图示例
代码为
Statistics.ScrollPositionData GetScrollPosition()
{
try
{
if (VisualTreeHelper.GetChildrenCount(dg_timing) > 0)
{
var border = VisualTreeHelper.GetChild(dg_timing, 0) as Decorator;
if (border != null)
{
var scroll = border.Child as ScrollViewer;
if (scroll != null)
{
return new Statistics.ScrollPositionData()
{
offset = (int)scroll.VerticalOffset,
rowId = (((DataRowView)dg_timing.Items[(int)scroll.VerticalOffset]).Row.ItemArray[((Statistics)DataContext).GetColumnOrder("Timeline")] as TextBlock).Text
};
}
}
}
}
catch (Exception) { }
return null;
}
但是现在我还有另一个问题-虚拟化。
如果我设置
EnableRowVirtualization="True"
EnableColumnVirtualization="True"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
并滚动到底部,刷新数据,我从顶部得到了一些行,但是滚动到顶部和后排都是正确的。 EnableRowVirtualization="False"
解决了问题,但是具有3000行的DataGrid加载速度太慢