2010-03-26 30 views
10

Sorun
Bir ViewModel bağlanan Krom şeklindeki sekmeleri kullanarak özel bir sekme denetimi vardır. Şekil yüzünden kenarlar biraz örtüşür. Sekmeler seçme ve sekme/sürükleme sekmeleri için iyi çalışıyor, ancak bir Röle Komutu ile bir sekme Ekleme veya Kapatma yaptığınızda, sıra dışı sonuçlar alıyorum tabeTem ZIndex TabControl_SelectionChanged ayarlayan bir işlevi var. Herhangi bir fikri olan var mı?WPF - Çakışan Özel bir TabControl sekmeler ve zIndex

Varsayılan görünüm: Arka arkaya 2 veya daha fazla Sekme Ekleme

:

Çıkarma Tabs

Bir kerede birden fazla sekme eklemek, yakın zamanda eklenen sekmelerin zindexini sıfırlamaz, böylece Sağdaki sekmenin arkasına giderler ve kapanış sekmeleri, onu değiştiren SelectedTab'ın ZIndex'ini doğru şekilde oluşturmaz ve arkada görünür. sağında sekme.

Kod ben doğru bunu ancak düzen değişiklikleri gösteren değil istediğim için zIndex ayarlıyor görebilirsiniz kesme noktaları kullanarak zIndex

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))); 
       } 
      } 
     } 
    } 

ayarlamak için. Bazı değişikliklerin geçerli olduğunu biliyorum çünkü bunların hiçbiri çalışmazsa, sekme kenarları tersine çevrilir (sağdaki sekmeler soldakilerin üzerine çizilir). Bir sekmeye tıklamak, tüm sekmelerin (en üstüne çizilmesi gereken) zindex'i ve bunları yeniden düzenlemek için sürükleyip/bırakarak doğru bir şekilde ayarlayacaktır (sekme öğesini kaldıran ve yeniden yükleyen). Düşünebildiğim tek fark, MVVM tasarım desenini ve Add/Close sekmelerinin geçiş komutları olan düğmeleri kullanıyorum.

Bunun neden olduğu ve bunun nasıl düzeltilebileceği konusunda herhangi bir fikri olan var mı?

p.s. ViewModel'imde bir ZIndex ayarlamayı ve ona bağlamayı denedim, ancak röle komutuyla sekmeleri eklerken/çıkarırken aynı şey gerçekleşir.

+0

Şimdi bunun WPF ile ilgili bir sorun olduğunu ve benim kodum olmadığını düşünüyorum. Sekme öğelerinin zIndexlerini çizildikten sonra gösteren bir düğme ekledim ve zIndex bunların hepsinde kesinlikle doğru, sadece doğru çizilmiyorlar. – Rachel

+0

Merhabalar. TabControl'de, Chrome benzeri yamuk şekilli bir sekmede sekmeler vermek ve onları doğru şekilde davranmak WPF'de oldukça zor görünüyor. Şablonlama/stil için kullandığınız XAML'yi paylaşma şansınız var mı? Burada bir çözüm var, ama özellikle zarif değil - ne yaptığını merak ediyorum! Şerefe. – Noldorin

+0

Elbette, kodun burada yayınlanması biraz uzun ama bunu açıklamaya çalışacağım. Sorularınız varsa bana e-posta göndermekten çekinmeyin [email protected] Her Sekme aslında 3 hücreli bir Izgaradır - Sol ve Sağ olanlar, eğriyi çizen ve ortadaki veriyi içeren bir Yol içerir. Her Kılavuzun, üst üste gelmesi için ayarlanmış bir negatif kenar boşluğu vardır ve zIndex, hangisinin en üstte olması gerektiğini belirlemek için kullanılır. Sürükle/bırak veya kaydırma eklediğinizden emin değilim, ancak benim durumumda, tüm Sekmeler kaydırma için bir ScrollViewer'da bulunur ve DragDrop, TabControl'ün ItemsControl için ekli bir özelliktir. – Rachel

cevap

5

Teşekkür ederim Abe, ikinci yorumunuz beni çözümüme yönlendiriyor!

Döngünün her yinelemesine tabItem.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate); ekledim.

Yine de, her değişiklikte her tabIt tazelemeden başka birinin bu şekilde bir yol bulup bulmadığını öğrenmek isterim. Döngü sonunda tüm sekme denetimini yenilemeyi denedim, ancak yalnızca sekmeleri kapatmak için değil, onları eklemek için çalıştı. Panel.ZIndex'in doğru şekilde ayarlandığını biliyorum, bu sadece render yaparken bu özelliği onurlandırmıyor.

DÜZENLEME: Yukarıdaki kod satırı, sürüklenen kişinin arkasındaki kısaca gösterilecek sekmeleri sürüklerken/çıkarırken alışılmadık bir titreme neden oldu. Kodu ayrı bir işleve taşıdım ve daha düşük bir dağıtıcı önceliği olarak adlandırdım ve bu sorunu çözdü. Son kod aşağıdadır:

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'a yükseltme de sorunu çözdü – Rachel

1

Toplama değiştiğinde algoritmanızı yeniden çalıştırmanız gerektiği gibi geliyor. ItemContainerGenerator.Status özelliğini test ettiğinizden, algoritma çalışmayabilir. StatusChanged olayını dinlemeyi düşünebilirsiniz ve ContainersGenerated'a dönüştüğünde algoritmayı yeniden çalıştırın.

+0

Bunu denedim ve hala düzgün görünmüyor. Ayrıca, ItemContainerGenerator.StatusChanged olayı SelectedItem güncelleştirilmeden önce çalışır, böylece her zaman seçili sekmeyi son seçilen sekmeye ayarlar. Kesme noktalarını kullanarak, TabControl_SelectionChanged olayını kullanarak sekmeleri eklerken/çıkarırken Panel.ZIndex öğesinin doğru şekilde ayarlandığını görebiliyorum, ancak gereken şekilde çizmiyor. Sürükle/Damlama sekmeleri (tabItem de kaldırır ve yeniden ekler) sekme sırasını doğru olarak çizdiğinden bu benim için anlamlı değildir. – Rachel

+2

Evet, bu garip. D & d ve sadece yeni bir öğe eklemek arasında düşünebildiğim tek fark, z-endeksi algoritmasının ne zaman çalıştığı zamanlamasıdır. Belki de Dispatcher'da daha düşük bir öncelikte (DispatcherPriority.Input gibi) çağırmak (hacky) bir çözüm olacaktır. –