2010-08-26 18 views
7

Bir ViewModel tarafından desteklenen UserControl üzerinde bir TabControl sahibim ve sekme öğelerinden birinin Visibility görünümü, ViewModel'deki bir özelliğe bağlıdır. WPF TabControl - TabItem Görünürlük değiştiğinde farklı sekmeyi seçin

<TabControl x:Name="myTabControl"> 
    <TabItem Header="Tab 1" /> 
    <TabItem Header="Tab 2" Visibility="{Binding HasData, Converter={StaticResource boolToVisibilityConverter}}"/> 
</TabControl> 

TabItem değişikliklerin Visibility, bu (gizler) TabItem başlık çöker, ancak içeriğini görüntüleyen devam

.

Diğer sekmesi gizli ve otomatik olmaz öğrenmek için biraz şaşırdım olduğu görülebilir sekmesine TabControl anahtarı istiyorum. TabControl ait SelectionChanged olaya bir olay işleyicisi ekleme

TabItem.Visibility değişiklikleri (bu bir hata ?!) olduğunda TabItem.IsSelected (ve TabControl.SelectedItem) bile etkilenmediğini göstermektedir.

<!-- This doesn't quite work, it affects the Visibility of the TabItem's content too --> 
    <TabControl.Style> 
     <Style TargetType="{x:Type TabControl}" BasedOn="{StaticResource {x:Type TabControl}}"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding Path=SelectedItem.Visibility, ElementName=tabControl}" 
          Value="Collapsed"> 
        <Setter Property="SelectedIndex" Value="0" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </TabControl.Style> 

Ben tetikleyiciler çalışmak olsun olamaz ve hiçbir VisibilityChanged var:

<!-- This doesn't compile because of TargetName on the Setter, think you can only use it in Control Templates. 
     I don't know how to refer to the parent TabControl from within the TabItem style. --> 
    <TabControl.ItemContainerStyle> 
     <Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}"> 
      <Style.Triggers> 
       <Trigger Property="Visibility" Value="Collapsed"> 
        <Setter TargetName="myTabControl" Property="SelectedIndex" Value="0" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </TabControl.ItemContainerStyle> 

ve veri tetikler: ben hem bir mülkiyet tetiği denedim

Ben halledebilir olay, bu yüzden sıkışmış ve bazı yardım için minnettarım.

cevap

4

TabItem sınıfının kullanabileceğiniz bir IsVisibleChanged olayı vardır.

+0

Ah, bu yapacak! (+1) Neden daha önce fark etmediğimi bilmiyorum - sanırım MSDN zamanda miras alınan mülkleri filtrelemeli. İşaretlemeyi kapalı tutacağım, bunun cevabı sadece birinin arkaplanda olmayan bir öneri olup olmadığını görmek için değil, ama çok teşekkür ederim. – Riko

2

SelectedIndex of TabControl öğesini bir özelliğe bağlayın. Ve bu özelliğin değerini, sekme öğesinin daraltılması için görünürlüğü değiştirdiğinizde görüntülemek istediğiniz sekme dizinine değiştirin.

1

Bu olay işleyicisini arkasındaki kodlara ekleyebilirsiniz. Denetiminizi ilk sırada ve bağlantılardan dolayı sekme görünürlüğünde değişiklikler üzerinde test edecektir.

Bunun yerine, bu OnLoaded'i yapmak yerine, bunu ekli bir Mülk haline getirmek tamamen mantıklıdır. (Otomatik seçim?) . Kod aynı. İlk sırada denir ve IsVisibleChanged'e olayları eklersiniz. Sonra tek hilesi, TabControl örneğini olay geri çağrısına almak için bir lambda (Parametre ciltleme) kullanmaktır. Bu çözümü gönderiyorum çünkü daha kısa.

private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e) 
{ 
    var tabControl = (TabControl) sender; 
    // register visibility changed to react on changes 
    foreach (TabItem item in tabControl.Items) 
    { 
     item.IsVisibleChanged += (mSender, ev) => item_IsVisibleChanged(mSender, ev, tabControl); 
    } 
    // if current selected tab is invisible, find and select first visible one. 
    if (!((TabItem) tabControl.SelectedItem).IsVisible) 
    { 
     foreach (TabItem item in tabControl.Items) 
     { 
      if (item.IsVisible) 
      { 
       tabControl.SelectedItem = item; 
       return; 
      } 
     } 
    } 
} 

private static void item_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e, TabControl tabControl) 
{ 
    // just became IsVisible = false 
    if ((bool)e.NewValue == false) 
    { 
     if (tabControl == null) return; 
     ItemCollection items = tabControl.Items; 
     foreach (UIElement item in items) 
     { 
      if (item.IsVisible) 
      { 
       tabControl.SelectedItem = item; 
       return; 
      } 
     } 
    } 
} 
İlgili konular