Ich habe eine TabControl
, in jedem TabItem
gibt es eine DataGrid
. Jede DataGridRow
hat eine Schaltfläche auf der DataGridRowHeader
, die die RowDetails
erweitert und reduziert.Einstellung DataGridRow RowDetails Sichtbarkeit nach dem Umschalten zwischen TabItems
Da ich die Zeile Details Erweiterung Funktionalität verwenden, so haben Sie die ScrollUnit VirtualizationPanel auf Pixel, so Scrollen ist ein bisschen natürlicher.
Das Programm erfasst, welche Zeilen in einem ObservableCollection<int>
erweitert wurden, der den zu erweiternden Zeilenindex enthält.
Wenn ich zu einem neuen TabItem
und zurück zum ursprünglichen TabItem
umschalte, verliert es, welche Reihen erweitert worden sind.
Nachdem die DataContext
geändert wurde, möchte ich die ObservableCollection
verwenden, um die erweiterten Zeilen zurückzusetzen. Ich habe dies im DataGrid
DataContextChanged
Ereignis versucht.
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;
}
}
Es ist jedoch nicht wie diese auf Reihen zu tun, die derzeit nicht in der VirtualizingPanel
sind.
Wie kann ich das erreichen?
Soll ich nur die derzeit virtualisierten Zeilen erweitern?
Sollte die DataGrid
ScrollViewer
auch programmgesteuert manipuliert werden? Wie kann ich die Zeilen berücksichtigen, die im ScrollViewer
nicht sichtbar sind?
Gibt es ein anderes Objekt, das andere DataGridRow
, dass ich die RowDetails
Visibility
einstellen sollte?
Haben Sie das meiste von dem, worüber Sie gesprochen haben, obwohl ich nur Code-Behind benutze. Mein Problem besteht nun darin, diese gespeicherten Daten wiederherzustellen. – Hank
Eine weitere Frage: Wenn also eine Reihe von RowDetails auf sichtbar gesetzt ist und der Benutzer sie vom VirtualizingPanel scrollt, werden die Zeilen zerstört. Wo behält das DataGrid diese Informationen, weil sie immer noch erweitert werden, wenn Sie sie zurück in die Ansicht scrollen? – Hank
Die Elemente werden aus einem vorherigen Container neu erstellt oder wiederverwendet, und die Details sind weiterhin sichtbar, weil eine Eigenschaft auf "True" oder "Visible" gesetzt ist. Aber das wird dir nicht helfen. – mm8