我TabControl
DataGrid
位于每个TabItem
内。它都是通过绑定填充的。我使用行详细信息扩展功能,因此将VirtualizingPanel
ScrollUnit
设置为Pixel
,因此滚动更自然一些。
在TabItems之间切换时,行选择正确。但是,在DataGrid的ScrollViewer
上设置垂直偏移,使其与您离开TabItem
时的位置完全相同,无法正常工作。
目前它的工作方式是,我在DataGrid
上有一个行为类。在Scrollviewer
ScrollChangedEvent
上,它会保存VerticalOffset
。更改为新TabItem
并更改回原始TabItem
后,在DataGrid的DataContextChanged
事件中,我将ScrollViewer的VerticalOffset
设置为已保存的VerticalOffset
。< / p>
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中加载了一个扩展行时,它变得更加怪异,跳跃更具戏剧性。
我希望滚动位置与我离开时的位置完全相同,我该如何实现?
答案 0 :(得分:1)
最简单的方法可能是在切换标签时阻止TabControl
卸载可视树。然后应保留每个标签的内容。
有关此内容的详情,请参阅以下链接。
How to stop Wpf Tabcontrol to unload Visual tree on Tab change
WPF - Elements inside DataTemplate property issue when no binding?