在TabItem之间切换后设置DataGridRow RowDetails可见性

时间:2017-09-11 01:37:55

标签: c# wpf wpfdatagrid tabcontrol rowdetails

我有一个ionic serve -l,每个TabControl都有一个TabItem。每个DataGridDataGridRow上都有一个按钮,可以展开和折叠DataGridRowHeader

由于我使用行详细信息扩展功能,因此将VirtualizingPanel ScrollUnit设置为Pixel,因此滚动更自然。

该程序捕获在RowDetails中展开的行,该行保存行索引以进行扩展。

当我切换到新的ObservableCollection<int>并返回到原始TabItem时,它会丢失哪些行已展开。

更改TabItem后,我想使用DataContext重置展开的行。我在ObservableCollection DataGrid事件中尝试了此操作。

DataContextChanged

但是,它不喜欢在当前不在public class DataGridBehaviors : Behavior<DataGrid>{ protected override void OnAttached(){ base.OnAttached(); this.AssociatedObject.DataContextChanged += DataGrid_DataContextChanged; } protected override void OnDetaching(){ 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; Task.Factory.StartNew(() => { PerformRowExpansions(newModuleGeometry); }); ScrollViewer scrollViewer = GetVisualChild<ScrollViewer>(this.AssociatedObject); if (scrollViewer != null){ /* * do some stuff */ } } private void PerformRowExpansions(ModuleGeometry newModuleGeometry){ ObservableCollection<int> tempExpandedIndexes = new ObservableCollection<int>(newModuleGeometry.ExpandedIndexes); newModuleGeometry.ExpandedIndexes = new ObservableCollection<int>(); if (this.Dispatcher.CheckAccess()){ foreach (int index in tempExpandedIndexes) { DataGridRow row = this.AssociatedObject.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow; row.DetailsVisibility = Visibility.Visible; } } else{ this.Dispatcher.Invoke(new Action(() =>{ foreach (int index in tempExpandedIndexes){ DataGridRow row = this.AssociatedObject.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow; row.DetailsVisibility = Visibility.Visible; } })); } } 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; } }

中的行上执行此操作

我怎样才能做到这一点?
我应该只扩展当前虚拟化的行吗?
是否应该以编程方式操作VirtualizingPanel DataGrid?如何说明ScrollViewer中不可见的行? 是否有另一个对象,ScrollViewer,我应该将DataGridRow RowDetails设置为?

1 个答案:

答案 0 :(得分:1)

DataGridRow中当前没有的行没有VirtualizingPanel个容器。这就是虚拟化的工作原理。

如果要在制表符开关之间保留一些信息,则应存储要在视图模型中保留的数据。例如,您可以将Button中的DataGridRowHeader绑定到某个命令,该命令可添加和删除基础数据类中集合的索引,即父DataContext的{​​{1}} ,DataGridRowTabItem

除非禁用UI虚拟化,否则尝试遍历可视TabControl容器将无效。这当然可能导致性能问题。