title: Setting DataGridRow RowDetails visibility after toggling between TabItems
body: <p>I have a <code>TabControl</code>, in each <code>TabItem</code> there is a <code>DataGrid</code>. Each <code>DataGridRow</code> has a button on the <code>DataGridRowHeader</code>, which expands and collapses the <code>RowDetails</code>.</p>
  
  <p>As I use the row details expansion functionality, so have set the VirtualizingPanel ScrollUnit to Pixel, so scrolling is a bit more natural.</p>
  
  <p>The program captures which rows have been expanded in an <code>ObservableCollection&amp;lt;int&gt;</code> which holds the row index to expand.</p>
  
  <p>When I toggle to a new <code>TabItem</code> and back to the original <code>TabItem</code>, it loses which rows have been expanded.</p>
  
  <p>Upon the <code>DataContext</code> being changed, I'd like to use the <code>ObservableCollection</code> to reset the expanded rows. I have tried this in the <code>DataGrid</code> <code>DataContextChanged</code> event.</p>
  
  <pre><code>public class DataGridBehaviors : Behavior&lt;DataGrid&gt;{
      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(() =&gt; {
              PerformRowExpansions(newModuleGeometry);
          });
  
          ScrollViewer scrollViewer = GetVisualChild&lt;ScrollViewer&gt;(this.AssociatedObject);
          if (scrollViewer != null){
              /*
               * do some stuff
               */
          }
      }
  
      private void PerformRowExpansions(ModuleGeometry newModuleGeometry){
          ObservableCollection&lt;int&gt; tempExpandedIndexes = new ObservableCollection&lt;int&gt;(newModuleGeometry.ExpandedIndexes);
          newModuleGeometry.ExpandedIndexes = new ObservableCollection&lt;int&gt;();
  
          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(() =&gt;{
                  foreach (int index in tempExpandedIndexes){
                      DataGridRow row = this.AssociatedObject.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow;
                      row.DetailsVisibility = Visibility.Visible;
                  }
              }));
          }
      }
  
      private static T GetVisualChild&lt;T&gt;(DependencyObject parent) where T : Visual{
          T child = default(T);
  
          int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
          for (int i = 0; i &lt; numVisuals; i++){
              Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
              child = v as T;
              if (child == null)
                  child = GetVisualChild&lt;T&gt;(v);
              if (child != null)
                  break;
          }
          return child;
      }
  }
  </code></pre>
  
  <p>However, it doesn't like doing this on rows that are not currently in the <code>VirtualizingPanel</code>.</p>
  
  <p>How can I accomplish this? <br/>
  Should I just do the expand the currently virtualized rows? <br/>
  Should the <code>DataGrid</code> <code>ScrollViewer</code> be manipulated programmatically as well? How can I account for the rows not visible in the <code>ScrollViewer</code>?<br/>
  Is there another object, other the <code>DataGridRow</code> that I should be setting the <code>RowDetails</code> <code>Visibility</code> to?</p>