我有一个ionic serve -l
,每个TabControl
都有一个TabItem
。每个DataGrid
在DataGridRow
上都有一个按钮,可以展开和折叠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
设置为?
答案 0 :(得分:1)
DataGridRow
中当前没有的行没有VirtualizingPanel
个容器。这就是虚拟化的工作原理。
如果要在制表符开关之间保留一些信息,则应存储要在视图模型中保留的数据。例如,您可以将Button
中的DataGridRowHeader
绑定到某个命令,该命令可添加和删除基础数据类中集合的索引,即父DataContext
的{{1}} ,DataGridRow
或TabItem
。
除非禁用UI虚拟化,否则尝试遍历可视TabControl
容器将无效。这当然可能导致性能问题。