Gibt es im Standard-WPF-Registerkartensteuerelement ein ausgewähltes Ereignis mit geänderter Registerkarte?


96

Gibt es in WPF ein Ereignis, mit dem bestimmt werden kann, wann sich TabControldie ausgewählte Registerkarte von a ändert?

Ich habe es versucht, TabControl.SelectionChangedaber es wird oft ausgelöst, wenn die Auswahl eines Kindes innerhalb eines Tabs geändert wird.

Antworten:


121

Ich habe dies im Handler gebunden, damit es funktioniert:

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

2
Ich dachte , das nicht funktionierte , aber dann merkte ich , dass ich für war die Überprüfung senderstatte.Source
Guillermo Ruffino

4
oder fügen e.Handled = trueSie einfach hinzu , um zu verhindern, dass es sprudelt
Brock Hensley

77

Wenn Sie die x:NameEigenschaft auf Folgendes festlegen TabItem:

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

Dann können Sie TabItembei der Veranstaltung auf jeden zugreifen :

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

Wenn Sie nur ein Ereignis haben möchten, wenn eine Registerkarte ausgewählt ist, ist dies der richtige Weg:

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

Und in deinem Code

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

Leider so schön wie dieses aussieht, ich bekomme die Selected-Eigenschaft in xaml nicht zur Verfügung, nur die IsSelected. Es tut uns leid.
PHenry

Ich stehe korrigiert ... irgendwie. DOH! Wenn ich versuche, in VS über das Obige zu tippen, bekomme ich die roten Kringel, daher dachte ich, es sei falsch. ABER als ich es eingeschnitten und eingeblendet habe und es einfach blind gemacht habe, hat es zu meinem Erstaunen funktioniert. HUH?! Warum hat es so funktioniert?
PHenry

Wie kann ich auf das Ereignis "Selector.Selected" im Code anstatt auf xaml zugreifen
Ahmed_Faraz

15

Sie können dieses Ereignis weiterhin verwenden. Überprüfen Sie einfach, ob das Absenderargument das Steuerelement ist, das Sie wirklich interessiert, und führen Sie in diesem Fall den Ereigniscode aus.


4

Das generierte Ereignis sprudelt, bis es behandelt wird.

Dieser XAML - Abschnitt unter Trigger ui_Tab_Changednach , ui_A_Changedwenn das Element in den ausgewählten ListViewÄnderungen, unabhängig von TabItemVeränderung in dem TabControl.

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

Wir müssen das Ereignis in ui_A_Changed( ui_B_Changedund so weiter) konsumieren :

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

2

Das ist das richtige Ereignis. Vielleicht ist es nicht richtig verkabelt?

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

im Codebehind ....

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

Wenn ich einen Haltepunkt in der Zeile i = 34 setze, wird dieser NUR unterbrochen, wenn ich Registerkarten ändere, selbst wenn die Registerkarten untergeordnete Elemente enthalten und eines davon ausgewählt ist.


Wenn Sie ein Raster in die Registerkarte einfügen, sprudelt die Auswahl einer Rasterzeile bis zum ausgewählten Ereignis der Registerkarte, wenn es nicht behandelt wird, bevor es dort ankommt.
Paul Swetz

2

Dieser Code scheint zu funktionieren:

    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

Wenn Sie das MVVM-Muster verwenden, ist es unpraktisch (und bricht das Muster), den Ereignishandler zu verwenden. Stattdessen können Sie die Selector.IsSelectedEigenschaften jedes einzelnen TabItems an eine Abhängigkeitseigenschaft in Ihrem Ansichtsmodell binden und dann den PropertyChangedEreignishandler behandeln. Auf diese Weise wissen Sie genau, welche Registerkarte basierend auf dem ausgewählt / abgewählt wurde, PropertyNameund Sie haben für jede Registerkarte einen speziellen Handler.

Beispiel: MainView.xaml

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

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

Wenn Ihr MainViewModelist INotifyPropertyChangednicht DependencyObject, dann verwenden Sie stattdessen:

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

Wenn jemand die moderne Benutzeroberfläche von WPF verwendet, kann er das Ereignis OnTabSelected nicht verwenden. Er kann jedoch das Ereignis SelectedSourceChanged verwenden.

so was

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

C # -Code ist

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
Die Verwendung von Argumenten von Drittanbietern ist niemals eine Lösung und sollte dringend empfohlen werden.
Steven Borges

@steven Ich habe dies für WPF MUI geschrieben und dies ist auch keine Antwort auf die Frage. Aber dies könnte eine Antwort sein, wpf mui user. Deshalb habe ich dies als Antwort angegeben. Vielen Dank
Sandun Harshana
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.