【发布时间】:2017-09-10 04:26:18
【问题描述】:
我有TabControl,每个TabItem 内部都有一个DataGrid。它都是通过绑定填充的。我使用了行详细信息扩展功能,所以将VirtualizingPanelScrollUnit设置为Pixel,这样滚动更自然一点。
在 TabItems 之间进行更改时,我的行选择行为正确。但是,在 DataGrid 的 ScrollViewer 上设置垂直偏移量,使其与您离开 TabItem 时的位置完全相同。
目前它的工作方式是,我在DataGrid 上有一个行为类。在 Scrollviewer ScrollChangedEvent 上,它保存了 VerticalOffset。在更改为新的TabItem 并更改回原来的TabItem 后,在DataGrid 的DataContextChanged 事件中,我将ScrollViewer 的VerticalOffset 设置为保存的VerticalOffset。
public class DataGridBehaviors : Behavior<DataGrid>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.DataContextChanged += DataGrid_DataContextChanged;
this.AssociatedObject.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(DataGridScrollViewer_ScrollChanged));
}
protected override void OnDetaching()
{
Console.WriteLine("OnDetaching");
this.AssociatedObject.RemoveHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(DataGridScrollViewer_ScrollChanged));
this.AssociatedObject.DataContextChanged -= DataGrid_DataContextChanged;
base.OnDetaching();
}
private void DataGrid_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
ModuleGeometry oldModuleGeometry = (ModuleGeometry)e.OldValue;
ModuleGeometry newModuleGeometry = (ModuleGeometry)e.NewValue;
ScrollViewer scrollViewer = GetVisualChild<ScrollViewer>(this.AssociatedObject);
if (scrollViewer != null)
{
scrollViewer.ScrollToVerticalOffset(newModuleGeometry.VerticalScrollPosition);
}
}
private void DataGridScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
ModuleGeometry modGeom = (ModuleGeometry)this.AssociatedObject.DataContext;
modGeom.VerticalScrollPosition = e.VerticalOffset;
}
private static T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}
}
发生的情况是您向下滚动并且顶部的 DataGridRow 部分显示(您只能看到其中的一半)。然后,当您在两个 TabItem 之间切换时,程序会正确设置 VerticalOffset,但随后会再次自动重置到部分显示行的顶部(完全显示)。
切换之前。将 VertcialOffset 保存到 4327.2 切换回原始 TabItem 后将 VerticalOffset 设置为 4327.2,然后出于某种原因并以某种方式自动将 VerticalOffset 重置为 4321.5,这是“以前”部分可见行的顶部
当您在 VirtualizingPanel 中加载扩展行时,它会变得更加奇怪,跳跃更加剧烈。
我想看到滚动位置与我离开时完全相同的位置,我该如何做到这一点?
【问题讨论】:
标签: c# wpf datagrid tabcontrol scrollviewer