2017-09-11 3 views
-1

TabControl이 있고 TabItem에는 DataGrid이 있습니다. 각 DataGridRow에는 DataGridRowHeader에 단추가 있으며,이 단추는 RowDetails을 펼치거나 접습니다.TabItem 간의 전환 후 DataGridRow RowDetails 가시성 설정

행 세부 정보 확장 기능을 사용하므로 VirtualizingPanel ScrollUnit을 Pixel로 설정 했으므로 스크롤이 좀 더 자연 스럽습니다.

확장 할 행 인덱스를 보유하고있는 ObservableCollection<int>에서 어떤 행이 확장되었는지 캡처합니다.

TabItem으로 전환하고 원래 TabItem으로 돌아 가면 확장 된 행이 손실됩니다.

DataContext이 변경되면 ObservableCollection을 사용하여 확장 된 행을 재설정하고 싶습니다. 나는 DataGridDataContextChanged 이벤트에서 이것을 시도했다.

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에없는 행에이 일을 좋아하지 않는다.

어떻게하면됩니까?
현재 가상화 된 행을 확장해야합니까?
DataGridScrollViewer도 프로그래밍 방식으로 조작해야합니까? ScrollViewer에 표시되지 않는 행을 어떻게 처리 할 수 ​​있습니까?
DataGridRow 다른 객체가 있습니까? RowDetailsVisibility을 설정해야합니까?

답변

1

현재 VirtualizingPanel에없는 행에 대한 컨테이너는 DataGridRow입니다. 그것이 가상화가 작동하는 방식입니다.

탭 스위치간에 정보를 유지하려면보기 모델에 유지할 데이터를 저장해야합니다. 예를 들어 DataGridRowHeader에있는 Button을 기본 데이터 클래스의 컬렉션 (예 : , TabItem 또는 TabControl)의 인덱스에 추가하고 제거하는 명령에 바인드 할 수 있습니다.

UI 가상화를 사용하지 않도록 설정하지 않으면 시각적 인 DataGridRow 컨테이너를 통해 반복을 시도해도 작동하지 않습니다. 그리고 이것은 물론 성능 문제를 일으킬 수 있습니다.

+0

내가 코드 숨김을 사용하고있을지라도, 여러분이 이야기 한 내용 대부분을 넣었습니다. 내 문제는 이제 저장된 데이터를 복원하는 것입니다. – Hank

+0

또 하나의 질문 : RowDetails 묶음이 표시되도록 설정 한 다음 사용자가 VirtualizingPanel에서 스크롤하면 행이 삭제됩니다. DataGrid는이 정보를 다시 볼 때 다시 펼쳐지기 때문에 어디에 보관합니까? – Hank

+1

요소가 이전 컨테이너에서 다시 생성되거나 다시 사용되며 일부 속성이 true 또는 Visible로 설정되어 있기 때문에 세부 정보가 계속 표시됩니다. 그러나 이것은 당신을 돕지 않을 것입니다. – mm8