我有一个TabControl
,在每个TabItem
中有一个DataGrid
。每个DataGridRow
在DataGridRowHeader
上都有一个按钮,用于展开和折叠RowDetails
。在TabItems之间切换后设置DataGridRow RowDetails
由于我使用行细节扩展功能,因此将VirtualizingPanel ScrollUnit设置为Pixel,因此滚动更自然一些。
该程序捕获哪些行已被扩展为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
Visibility
?
尽管我只是使用了代码隐藏功能,但已经把大部分内容放在了里面。我现在的问题是恢复存储的数据。 – Hank
还有一个问题:因此,如果一堆RowDetails设置为可见,然后用户将它们从VirtualizingPanel滚动,这会导致行被销毁。 DataGrid在哪里保存这些信息,因为当你将它们滚动回视图时它们仍然展开? – Hank
这些元素是从先前的容器重新创建或重新使用的,并且由于某些属性设置为true或Visible,细节仍然可见。但这不会帮助你。 – mm8