2009-04-21 7 views

Respuesta

104

até esta en el controlador para que funcione:

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

pensé que esto no estaba funcionando, pero luego me di cuenta que era el registro de 'sender' en lugar de' e.Source' –

+4

o simplemente añadir 'e.Handled = true' para evitar que se burbujeando –

14

Aún puede usar ese evento. Simplemente verifique que el argumento del remitente sea el control que realmente le importa y, de ser así, ejecute el código del evento.

2

Ese es el evento correcto. Tal vez no está conectado correctamente?

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

en el código subyacente ....

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

si fijo un punto de interrupción en el i = 34 línea, sólo se rompe cuando cambio pestañas, incluso cuando las lengüetas tienen elementos secundarios y uno de ellos es seleccionado.

4

El evento generado está burbujeando hacia arriba hasta que se maneja.

Esta porción xaml debajo desencadena ui_Tab_Changed después ui_A_Changed cuando el elemento seleccionado en el ListView cambios, independientemente de TabItem cambio en la TabControl.

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

necesitamos consumir el evento en ui_A_Changed (y ui_B_Changed, y así sucesivamente):

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

Si se establece la propiedad x:Name a cada TabItem como:

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

Entonces Puede acceder a cada TabItem en el 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

Este código parece funcionar:

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

Si lo que desea es tener un evento cuando se selecciona una ficha, ésta es la forma correcta:

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

Y en su código

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

desgracia tan bonito como se ve, no obtengo la propiedad Selected disponible en xaml, solo la IsSelected. Lo siento. – PHenry

+0

Me corrigen ... tipo de. DOH! Cuando trato de escribir sobre lo anterior en VS, me da los squigglies rojos, por lo tanto, pensé que estaba mal. PERO cuando lo corté y simplemente lo vi a ciegas, para mi sorpresa, FUNCIONÓ. HUH ?! ¿Por qué funcionó de esa manera? – PHenry

0

Si alguien utiliza la interfaz de usuario moderna de WPF, no pueden usar el evento OnTabSelected, pero pueden usar el evento SelectedSourceChanged.

como esto

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

código C# es

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

El uso de argumentos de terceros nunca es una solución y debe desaconsejarse enérgicamente. –

+0

@steven Escribí esto para WPF MUI y esta no es la respuesta a la pregunta también. Pero esto podría ser una respuesta para el usuario mui. Por eso lo puse como una respuesta. gracias –

0

Si está utilizando el patrón MVVM entonces es un inconveniente (y rompe el patrón) para utilizar el controlador de eventos. En su lugar, puede vincular la propiedad Selector.IsSelected de cada TabItem individual a una propiedad de dependencia en su modelo de vista y luego manejar el controlador de eventos PropertyChanged. De esta forma, sabrá exactamente qué pestaña fue seleccionada/deseleccionada según el PropertyName y tendrá un controlador especial para cada pestaña.

Ejemplo: MainView.xaml

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

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

Si su MainViewModel es INotifyPropertyChanged en lugar de DependencyObject, a continuación, utilizar esto en su lugar:

Ejemplo: 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 
} 
} 
Cuestiones relacionadas