2009-04-21 9 views

risposta

104

ho legato questo nel gestore per farlo funzionare:

void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    if (e.Source is TabControl) 
    { 
     //do work when tab is changed 
    } 
} 
+1

ho pensato che questo non funzionava, ma poi mi resi conto che stavo controllando per 'sender' invece di' e.Source' –

+4

o semplicemente aggiungere 'e.Handled = true' per evitare che ribolle –

14

Si può ancora usare quell'evento. Controlla che l'argomento del mittente sia il controllo che ti interessa davvero e, in tal caso, esegui il codice dell'evento.

2

Questo è l'evento corretto. Forse non è cablato correttamente?

<TabControl SelectionChanged="TabControl_SelectionChanged"> 
    <TabItem Header="One"/> 
    <TabItem Header="2"/> 
    <TabItem Header="Three"/> 
</TabControl> 

nel codebehind ....

private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    int i = 34; 
} 

se ho impostato un punto di interruzione sulla linea i = 34, si rompe solo quando cambio le schede, anche quando le schede sono elementi figlio e una di loro è selezionato.

4

L'evento generato è zampillante fino a quando non viene gestito.

Questa porzione XAML sotto innesca ui_Tab_Changed dopo ui_A_Changed quando l'elemento selezionato nella ListView modifiche, indipendentemente dal TabItem cambiamento nella TabControl.

<TabControl SelectionChanged="ui_Tab_Changed"> 
    <TabItem> 
    <ListView SelectionChanged="ui_A_Changed" /> 
    </TabItem> 
    <TabItem> 
    <ListView SelectionChanged="ui_B_Changed" /> 
    </TabItem> 
</TabControl> 

abbiamo bisogno di consumare l'evento in ui_A_Changed (e ui_B_Changed, e così via):

private void ui_A_Changed(object sender, SelectionChangedEventArgs e) { 
    // do what you need to do 
    ... 
    // then consume the event 
    e.Handled = true; 
} 
62

Se si imposta la proprietà x:Name ad ogni TabItem come:

<TabControl x:Name="MyTab" SelectionChanged="TabControl_SelectionChanged"> 
    <TabItem x:Name="MyTabItem1" Header="One"/> 
    <TabItem x:Name="MyTabItem2" Header="2"/> 
    <TabItem x:Name="MyTabItem3" Header="Three"/> 
</TabControl> 

Poi puoi accedere a ogni TabItem all'evento:

private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    if (MyTabItem1.IsSelected) 
    // do your stuff 
    if (MyTabItem2.IsSelected) 
    // do your stuff 
    if (MyTabItem3.IsSelected) 
    // do your stuff 
} 
2

Questo codice sembra funzionare:

private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     TabItem selectedTab = e.AddedItems[0] as TabItem; // Gets selected tab 

     if (selectedTab.Name == "Tab1") 
     { 
      // Do work Tab1 
     } 
     else if (selectedTab.Name == "Tab2") 
     { 
      // Do work Tab2 
     } 
    } 
26

Se si vogliono solo avere un evento quando si seleziona una scheda, questo è il modo corretto:

<TabControl> 
    <TabItem Selector.Selected="OnTabSelected" /> 
    <TabItem Selector.Selected="OnTabSelected" /> 
    <TabItem Selector.Selected="OnTabSelected" /> 
    <!-- You can also catch the unselected event --> 
    <TabItem Selector.Unselected="OnTabUnSelected" /> 
</TabControl> 

E nel codice

+0

Purtroppo così bello come questo, non ho la proprietà Selected disponibile per me in xaml, solo l'IsSelected. Scusate. – PHenry

+0

Sono corretto .... tipo. DOH! Quando provo a digitare su quanto sopra in VS, mi dà gli squigglie rossi, quindi ho pensato che fosse sbagliato. MA, quando l'ho tagliato dentro e lo ho fiaccato ciecamente, con mio grande stupore, ha funzionato. Eh ?! Perché ha funzionato in quel modo? – PHenry

0

Se qualcuno utilizza l'interfaccia utente moderna WPF, non può utilizzare l'evento OnTabSelected, ma può utilizzare l'evento SelectedSourceChanged.

come questo

<mui:ModernTab Layout="Tab" SelectedSourceChanged="ModernTab_SelectedSourceChanged" Background="Blue" AllowDrop="True" Name="tabcontroller" > 

codice C# è

private void ModernTab_SelectedSourceChanged(object sender, SourceEventArgs e) 
    { 
      var links = ((ModernTab)sender).Links; 

      var link = this.tabcontroller.Links.FirstOrDefault(l => l.Source == e.Source); 

      if (link != null) { 
       var index = this.tabcontroller.Links.IndexOf(link); 
       MessageBox.Show(index.ToString()); 
      }    
    } 
+2

L'utilizzo di argomenti di terze parti non è mai una soluzione e dovrebbe essere fortemente scoraggiato. –

+0

@steven Ho scritto questo per WPF MUI e questa non è la risposta alla domanda too.but questo potrebbe essere la risposta wpf mui user.That è il motivo per cui ho messo questo come risposta. grazie –

0

Se si sta utilizzando il modello MVVM, allora è scomodo (e rompe lo schema) per utilizzare il gestore di eventi. Invece, è possibile associare la proprietà Selector.IsSelected di ogni TabItem a una proprietà di dipendenza nel viewmodel e quindi gestire il gestore di eventi PropertyChanged. In questo modo sai esattamente quale scheda è stata selezionata/deselezionata in base allo PropertyName e disponi di un gestore speciale per ogni scheda.

Esempio: MainView.xaml

<TabControl> 
<TabItem Header="My tab 1" Selector.IsSelected="{Binding IsMyTab1Selected}"> ... </TabItem> 
<TabItem Header="My tab 2" Selector.IsSelected="{Binding IsMyTab2Selected}"> ... </TabItem> 
</TabControl> 

Esempio: MainViewModel.cs

public bool IsMyTab1Selected { 
get { return (bool)GetValue(IsMyTab1SelectedProperty); } 
set { SetValue(IsMyTab1SelectedProperty, value); } 
} 
public static readonly DependencyProperty IsMyTab1SelectedProperty = 
DependencyProperty.Register("IsMyTab1Selected", typeof(bool), typeof(MainViewModel), new PropertyMetadata(true, new PropertyChangedCallback(MyPropertyChanged))); 

public bool IsMyTab2Selected { 
get { return (bool)GetValue(IsMyTab2SelectedProperty); } 
set { SetValue(IsMyTab2SelectedProperty, value); } 
} 
public static readonly DependencyProperty IsMyTab2SelectedProperty = 
DependencyProperty.Register("IsMyTab2Selected", typeof(bool), typeof(MainViewModel), new PropertyMetadata(false, new PropertyChangedCallback(MyPropertyChanged))); 

private void MyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
if (e.Property.Name == "IsMyTab1Selected") { 
    // stuff to do 
} else if (e.Property.Name == "IsMyTab2Selected") { 
    // stuff to do 
} 
} 

Se il MainViewModel è INotifyPropertyChanged piuttosto che DependencyObject, quindi utilizzare questo invece:

Esempio: MainViewModel.cs

public event PropertyChangedEventHandler PropertyChanged; 
protected virtual void OnPropertyChanged(string propertyName) { 
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
} 

public MainViewModel() { 
PropertyChanged += handlePropertyChanged; 
} 

public bool IsMyTab1Selected { 
get { return _IsMyTab1Selected ; } 
set { 
    if (value != _IsMyTab1Selected) { 
    _IsMyTab1Selected = value; 
    OnPropertyChanged("IsMyTab1Selected "); 
    } 
} 
} 
private bool _IsMyTab1Selected = false; 

public bool IsMyTab2Selected { 
get { return _IsMyTab2Selected ; } 
set { 
    if (value != _IsMyTab2Selected) { 
    _IsMyTab2Selected = value; 
    OnPropertyChanged("IsMyTab2Selected "); 
    } 
} 
} 
private bool _IsMyTab2Selected = false; 

private void handlePropertyChanged(object sender, PropertyChangedEventArgs e) { 
if (e.PropertyName == "IsMyTab1Selected") { 
    // stuff to do 
} else if (e.PropertyName == "IsMyTab2Selected") { 
    // stuff to do 
} 
} 
Problemi correlati