2010-03-26 3 views
10

문제
은 내가 뷰 모델에 결합 크롬 모양의 탭을 사용하여 사용자 지정 탭을 제어 할 수 있습니다. 모양 때문에 가장자리가 조금 겹칩니다. 나는 탭을 선택하고 탭을 드래그/드롭하는 것에 대해 잘 작동하는 TabControl_SelectionChanged에 tabItem의 ZIndex를 설정하는 함수를 가지고 있습니다. 그러나 릴레이 명령을 통해 탭을 추가하거나 닫으면 비정상적인 결과가 나타납니다. 누구든지 아이디어가 있습니까?WPF - 중복 사용자 지정을 TabControl에서 탭 및 Z- 색인

기본보기 : 연속으로 2 개 이상의 탭을 추가

:

제거 탭

한 번에 두 개 이상의 탭을 추가하면 최근 추가 된 다른 탭의 zindex가 다시 설정되지 않으므로 오른쪽의 탭 뒤쪽으로 이동하고 닫는 탭이 SelectedTab의 ZIndex를 올바르게 렌더링하지 않으므로 해당 탭의 뒤에 표시됩니다. 탭 오른쪽에 있습니다.

코드는 내가 제대로 나는 그것이 그러나 레이아웃이 변경 사항을 표시하지 않습니다 싶은에 Z- 색인을 설정하고 있음을 볼 수 있습니다 중단 점을 사용하여 Z- 색인

private void PrimaryTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (e.Source is TabControl) 
     { 
      TabControl tabControl = sender as TabControl; 
      ItemContainerGenerator icg = tabControl.ItemContainerGenerator; 
      if (icg.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) 
      { 
       foreach (object o in tabControl.Items) 
       { 
        UIElement tabItem = icg.ContainerFromItem(o) as UIElement; 
        Panel.SetZIndex(tabItem, (o == tabControl.SelectedItem ? 100 : 
         90 - tabControl.Items.IndexOf(o))); 
       } 
      } 
     } 
    } 

을 설정합니다. 변경 사항 중 일부는 작동하지 않는다면 탭 가장자리가 바뀌므로 (오른쪽 탭이 왼쪽 탭 위에 그려지기 때문) 탭을 클릭하면 모든 탭 (그 위에 그려야하는 탭 포함)의 zindex를 올바르게 설정하고 다시 드래그/드롭하여 다시 정렬하면 올바르게 렌더링됩니다 (탭 항목을 제거하고 다시 삽입 함). 내가 생각할 수있는 유일한 차이점은 MVVM 디자인 패턴과 Add/Close 탭이 릴레이 명령이라는 버튼을 사용하고 있다는 것입니다.

왜 이런 일이 발생하고 어떻게 해결할 수 있는지 알 수있는 사람이 있습니까?

p.s. 내 ViewModel에서 ZIndex를 설정하고 바인딩하려고했지만 릴레이 명령을 통해 탭을 추가/제거 할 때 동일한 문제가 발생합니다.

+0

이제는 WPF 및 제 코드에 문제가 있다고 생각합니다. 나는 탭 항목의 zIndex를 표시 한 버튼을 그려서 가져 왔고 zIndex는 모두 정확하게 맞았으며 올바르게 그려지지 않았습니다. – Rachel

+0

안녕하세요. TabControl에서 크롬과 같은 사다리꼴 모양을 탭하고 올바르게 동작하도록 만드는 것은 실제로 WPF에서 매우 까다로운 것으로 보입니다. 템플릿/스타일에 사용한 XAML을 공유 할 수있는 기회가 있습니까? 여기에 해결책이 있지만, 특별히 우아하지는 않습니다. - 당신이 한 일이 궁금합니다! 건배. – Noldorin

+0

물론 코드는 여기에 게시하기에는 너무 길지만 설명해 보겠습니다. 궁금한 점이 있으시면 언제든지 [email protected]로 이메일을 보내주십시오. 각 탭은 실제로 3 개의 셀이있는 격자입니다. 왼쪽 및 오른쪽 셀에는 곡선을 그리는 경로가 있고 중간에는 곡선이 그려져 있습니다. 각 그리드에는 음수 여백이 설정되어 겹치게 설정되고 zIndex는 어느 것이 위에 있어야하는지 설정하는 데 사용됩니다. 드래그/드롭 또는 스크롤링을 추가하고 있는지는 확실하지 않지만 제 경우에는 모든 탭이 스크롤을 위해 ScrollViewer에 포함되어 있으며 DragDrop은 TabControl의 ItemsControl에 대한 연결된 속성입니다. – Rachel

답변

5

감사합니다. 아베, 두 번째 코멘트는 저의 해결책으로 이어졌습니다!

루프의 각 반복마다 tabItem.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);을 추가했습니다.

다른 사람들이 모든 변경 사항에 대해 각 tabItem을 새로 고치지 않고이 문제를 해결할 수 있다면 여전히 학습에 관심이 있습니다. 루프의 끝에서 전체 탭 컨트롤을 새로 고쳐 보았지만 탭을 닫을 때만 추가했습니다. Panel.ZIndex가 올바르게 설정되고 있다는 것을 알고 있습니다. 렌더링 할 때 해당 속성을 인식하지 못합니다.

편집 : 위의 코드 줄은 끌어서 놓은 탭 뒤의 탭을 잠시 표시하는 탭을 끌거나 놓을 때 비정상적인 깜박임을 유발합니다. 코드를 별도의 함수로 옮기고 디스패처 우선 순위를 낮추면이 문제가 해결되었습니다. 최종 코드는 다음과 같습니다.

private void PrimaryTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (e.Source is TabControl) 
     { 
      TabControl tabControl = sender as TabControl; 

      tabControl.Dispatcher.BeginInvoke(
       new Action(() => UpdateZIndex(sender as TabControl)), 
       DispatcherPriority.Background); 
     } 
    } 

    private void UpdateZIndex(TabControl tabControl) 
    { 
     ItemContainerGenerator icg = tabControl.ItemContainerGenerator; 

     if (icg.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) 
     { 
      foreach (object o in tabControl.Items) 
      { 
       UIElement tabItem = icg.ContainerFromItem(o) as UIElement; 
       if (tabItem != null) 
       { 
        // Set ZIndex 
        Panel.SetZIndex(tabItem, (o == tabControl.SelectedItem ? 100 : 
         90 - tabControl.Items.IndexOf(o))); 
       } 
      } 
     } 
    } 
+1

.Net 4.0으로 업그레이드하면 문제가 해결됨 – Rachel

1

컬렉션이 변경 될 때 알고리즘을 다시 실행해야하는 것처럼 들립니다. ItemContainerGenerator.Status 속성을 테스트 중이므로 알고리즘이 실행되지 않을 수 있습니다. StatusChanged 이벤트를 청취하는 것이 좋습니다. ContainersGenerated으로 변경되면 알고리즘을 다시 실행하십시오.

+0

나는 이것을 시도했지만 여전히 올바르게 나타나지 않는다. 또한 SelectedItem이 업데이트되기 전에 ItemContainerGenerator.StatusChanged 이벤트가 실행되므로 선택된 탭이 마지막으로 선택한 탭으로 설정됩니다. 중단 점을 사용하면 TabControl_SelectionChanged 이벤트를 사용하여 탭을 추가/제거 할 때 Panel.ZIndex가 올바르게 설정되어 있음을 알 수 있습니다. TabItem을 제거하고 다시 추가하는 탭 드래그/드롭으로 탭 순서가 올바르게 그려지기 때문에 나에게이 의미가 없습니다. – Rachel

+2

그래, 이상하다. d & d 사이에서 생각할 수있는 유일한 차이점은 z- 색인 알고리즘을 실행할시기가 될 것입니다. 아마도 DispatcherPriority.Input과 같이 우선 순위가 낮은 Dispatcher에서이를 호출하면 해킹이 될 수 있습니다. –