È presente un evento di modifica della scheda selezionata nel controllo scheda WPF standard


96

In WPF, esiste un evento che può essere utilizzato per determinare quando TabControlcambia la scheda selezionata di una?

Ho provato a usare TabControl.SelectionChangedma viene attivato molte volte quando viene modificata la selezione di un bambino all'interno di una scheda.

Risposte:


121

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

2
Pensavo che non funzionasse, ma poi mi sono reso conto che stavo controllando senderinvece die.Source
Guillermo Ruffino

4
o semplicemente aggiungere e.Handled = trueper evitare che ribolle
Brock Hensley

77

Se imposti la x:Nameproprietà su ognuno TabItemcome:

<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>

Quindi puoi accedere a ciascuno TabItemdurante l'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
}

50

Se vuoi solo avere un evento quando una scheda è selezionata, 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 tuo codice

    private void OnTabSelected(object sender, RoutedEventArgs e)
    {
        var tab = sender as TabItem;
        if (tab != null)
        {
            // this tab is selected!
        }
    }

Sfortunatamente, per quanto carino, non ho la proprietà Selected disponibile in xaml, solo IsSelected. Scusate.
PHenry

Sono stato corretto .... più o meno. DOH! Quando provo a scrivere quanto sopra in VS, mi dà gli squiggli rossi, quindi ho pensato che fosse sbagliato. MA quando l'ho tagliato e incollato e l'ho fatto solo alla cieca, con mio grande stupore, ha funzionato. EH ?! Perché ha funzionato in questo modo?
PHenry

Come posso accedere all'evento "Selector.Selected" nel codice invece che in
xaml

15

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


4

L'evento generato ribolle finché non viene gestito.

Questa parte xaml di seguito si attiva ui_Tab_Changeddopo ui_A_Changedquando l'elemento selezionato nelle ListViewmodifiche, indipendentemente dalla TabItemmodifica nel file TabControl.

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

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

2

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

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

nel codice dietro ...

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

se imposto un punto di interruzione sulla riga i = 34, si interrompe SOLO quando cambio scheda, anche quando le schede hanno elementi figli e uno di essi è selezionato.


metti una griglia nella scheda, selezionando una riga della griglia apparirà una bolla fino all'evento selezionato nella scheda se non viene gestito prima che arrivi lì.
Paul Swetz

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

1

Se stai usando il pattern MVVM, è scomodo (e rompe il pattern) usare il gestore di eventi. Invece, puoi associare ogni singola Selector.IsSelectedproprietà TabItem a una proprietà di dipendenza nel tuo viewmodel e quindi gestire il PropertyChangedgestore di eventi. In questo modo sai esattamente quale scheda è stata selezionata / deselezionata in base a PropertyNamee hai 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 tuo MainViewModelè INotifyPropertyChangedinvece di DependencyObject, allora usa 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
 }
}

-1

Se qualcuno utilizza l'interfaccia utente moderna di 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" >

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

3
L'uso di argomenti di terze parti non è mai una soluzione e dovrebbe essere fortemente scoraggiato.
Steven Borges

@steven ho scritto questo per WPF MUI e anche questa non è una risposta alla domanda, ma questa potrebbe essere la risposta wpf mui user.Questo è il motivo per cui l'ho messo come risposta. grazie
Sandun Harshana
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.