wpf datagrid在更新数据后显示行

时间:2018-06-22 14:21:18

标签: c# wpf datagrid

我有带过滤器的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;
    }
  1. 重置数据网格项后调用源

    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提供文本编辑帮助

1 个答案:

答案 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加载速度太慢