我有一個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