Apakah ada Tab yang Dipilih Peristiwa Berubah dalam Kontrol Tab WPF standar

96

Di WPF, apakah ada peristiwa yang dapat digunakan untuk menentukan kapan TabControltab yang dipilih berubah?

Saya telah mencoba menggunakan TabControl.SelectionChangedtetapi sering kali dipecat ketika pilihan anak dalam tab diubah.

Jon Kragh
sumber

Jawaban:

122

Saya mengikat ini di pawang untuk membuatnya bekerja:

void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.Source is TabControl)
    {
      //do work when tab is changed
    }
}
Jon Kragh
sumber
2
Saya pikir ini tidak berfungsi tetapi kemudian saya menyadari bahwa saya sedang memeriksa senderalih - alihe.Source
Guillermo Ruffino
4
atau cukup tambahkan e.Handled = trueuntuk mencegahnya meluap
Brock Hensley
77

Jika Anda menyetel x:Nameproperti ke masing TabItem- masing sebagai:

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

Kemudian Anda dapat mengakses masing-masing TabItemdi acara tersebut:

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
}
tak terduga
sumber
50

Jika Anda hanya ingin mengadakan acara saat tab dipilih, ini adalah cara yang benar:

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

Dan dalam kode Anda

    private void OnTabSelected(object sender, RoutedEventArgs e)
    {
        var tab = sender as TabItem;
        if (tab != null)
        {
            // this tab is selected!
        }
    }
MicBig
sumber
Sayangnya sebaik yang ini terlihat, saya tidak mendapatkan properti Selected tersedia untuk saya di xaml, hanya IsSelected. Maaf.
PHenry
Saya berdiri dikoreksi .... jenis. DOH! Ketika saya mencoba untuk mengetik di atas di VS, itu memberi saya coretan merah, oleh karena itu saya pikir itu salah. TAPI ketika saya memotongnya dan secara membabi buta membacanya, saya heran, ITU BERHASIL. HAH?! Mengapa itu bekerja seperti itu?
PHenry
Bagaimana saya bisa mengakses acara "Selector.Selected" dalam kode alih-alih xaml
Ahmed_Faraz
15

Anda masih bisa menggunakan acara itu. Cukup periksa apakah argumen pengirim adalah kontrol yang benar-benar Anda pedulikan dan jika demikian, jalankan kode kejadian.

Nidonocu
sumber
4

Acara yang dihasilkan menggelembung hingga ditangani.

Bagian xaml di bawah ini dipicu ui_Tab_Changedsetelah ui_A_Changeditem yang dipilih dalam ListViewperubahan, terlepas dari TabItemperubahan di TabControl.

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

Kita perlu mengonsumsi acara di ui_A_Changed(dan ui_B_Changed, dan seterusnya):

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

Jika Anda menggunakan pola MVVM maka tidak nyaman (dan merusak pola) untuk menggunakan event handler. Sebagai gantinya, Anda bisa mengikat masing-masing Selector.IsSelectedproperti TabItem ke properti dependensi di viewmodel Anda lalu menangani PropertyChangedevent handler. Dengan begitu Anda tahu persis tab mana yang dipilih / batal dipilih berdasarkan PropertyNamedan Anda memiliki penangan khusus untuk setiap tab.

Contoh: MainView.xaml

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

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

Jika Anda MainViewModeladalah INotifyPropertyChangedbukan DependencyObject, kemudian gunakan ini sebagai gantinya:

Contoh: 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
 }
}
Nikola Novak
sumber
ini berhasil untuk saya;)
Blood-HaZaRd
2

Itu acara yang benar. Mungkin tidak terhubung dengan benar?

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

di belakang kode ....

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

jika saya menetapkan breakpoint pada baris i = 34, itu HANYA rusak ketika saya mengganti tab, bahkan ketika tab memiliki elemen anak dan salah satunya dipilih.

Muad'Dib
sumber
taruh kisi di tab, memilih baris kisi akan menggelembung ke tab yang dipilih acara jika tidak ditangani sebelum sampai di sana.
Paul Swetz
2

Kode ini sepertinya berfungsi:

    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
        }
    }
Mc_Topaz
sumber
-1

Jika ada yang menggunakan WPF Modern UI, mereka tidak dapat menggunakan acara OnTabSelected. Tetapi mereka dapat menggunakan acara SelectedSourceChanged.

seperti ini

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

Kode C # adalah

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());
          }            
    }
Sandun Harshana
sumber
3
Menggunakan argumen pihak ketiga tidak pernah menjadi solusi dan harus sangat tidak disarankan.
Steven Borges
@ steven saya menulis ini untuk WPF MUI dan ini bukan jawaban pertanyaan juga. tapi ini bisa jadi jawaban pengguna wpf mui. Itulah mengapa saya menempatkan ini sebagai jawaban. terima kasih
Sandun Harshana