私はTabControl
を持っています、それぞれTabItem
にはDataGrid
があります。各DataGridRow
にはDataGridRowHeader
にボタンがあり、RowDetails
を展開して折りたたみます。TabItem間の切り替え後に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
もう1つ質問:RowDetailsの束がvisibleに設定されている場合に、ユーザーがそれらをVirtualizingPanelからスクロールすると、行が破棄されます。 DataGridはこの情報をどこに保存しますか? – Hank
要素が以前のコンテナから再作成または再利用され、一部のプロパティがtrueまたはVisibleに設定されているため、詳細が表示されます。しかし、これはあなたを助けません。 – mm8