2010-09-07 11 views
45

Mam GUI z zakładkami z każdą zakładką zawierającą ramkę. W jednej z tych ram znajduje się DataGrid. Kiedy użytkownik wybierze tę kartę, potrzebuję posortować datagrid, więc używam zdarzenia TabControl SelectionChanged, aby wywołać sortowanie. Jednak zdarzenie to wyzwala za każdym razem, gdy element jest wybierany z DataGrid, mimo że same karty pozostają nienaruszone.W C# WPF, dlaczego moje zdarzenie SelectionChanged w TabControl jest uruchamiane zbyt często?

Próbowałem wiele różnych wydarzeń: GotFocus dla TabItem RequestBringIntoView dla TabItem

ale wszystkie one wydają się cierpieć z tego problemu. Co to powoduje?

Odpowiedz

78

TabControl.SelectionChanged to samo zdarzenie jako ComboBox.SelectionChanged

pochodzi on od Selector.SelectionChanged.

Jeśli więc nie oznaczysz swojego wydarzenia jako obsłużonego w programie obsługi zdarzeń, spowoduje to zbindowanie drzewa i ostatecznie dojdzie do Twojego numeru TabControl, co powoduje ten problem "zwalnianie zbyt często".

Oznacz to wydarzenie jako obsłużone w SelectionChanged Twojego ComboBox/ListBox/ListView/jakiejkolwiek innej Selector używanego w DataGrid tak:

private void MyComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    e.Handled = true; 
} 

I ta niedogodność odejdzie;).

+12

Następnie musiałby obsłużyć każdy selektor na każdej ze swoich kart. O wiele łatwiej jest po prostu spojrzeć i sprawdzić, czy e.OriginalSource to Kontrola zakładek. –

+1

To prawda, ale byłoby to czystsze, gdyby po prostu zaznaczył swoje wydarzenie jako Obsługiwane, gdy selektor zostanie z nim zrobiony. :) – Arcturus

+12

Dziękuję bardzo za wskazanie problemu. Jeśli chodzi o rozwiązanie, w końcu dodałem "if (e.OriginalSource is System.Windows.Controls.TabControl)" do mojego zdarzenia TabControl.SelectionChanged, więc nie musiałbym tworzyć procedury obsługi zdarzeń dla mojego Datagridu. – Anders

2

Jeśli dodano moduł obsługi z AddHandler w elemencie nadrzędnym, wszystkie zmiany wyboru będą wywoływać zdarzenie SelectionChanged. W takim przypadku możesz nadać swojemu TabControl nazwę, a następnie sprawdzić w EventHandler, jeśli nazwa OriginalSource jest nazwą twojego TabControl.

+0

W procedurze obsługi OnSelectedChanged, '' if (Equals (sender, e.OriginalSource)) {/ * wykonuję pracę * /} '' wtedy wszystkie dzieci Zdarzenia nie wejdą do warunkowego bloku –

2

Innym dobrym approch jest dodanie obsługi do tabControl.Items.SelectionChanged:

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    ItemCollection view = tabControl.Items; 
    view.CurrentChanged += new EventHandler(view_CurrentChanged); 
} 

void view_CurrentChanged(object sender, EventArgs e) 
{ 
    throw new NotImplementedException(); 
} 

Może nie jest xamly sposób, ale jest mniejszy ból jak on jedynie pożarów, gdy element zostanie zmieniona.

21
 
    private void tabControlName_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      if (e.Source is TabControl) //if this event fired from TabControl then enter 
      { 
       if (tabItemName.IsSelected) 
       { 
        //Do your job here 
       } 
      } 
     } 
+0

Używam kontrolek zakładki podrzędne w ramach kontrolki głównej zakładki, Czy możemy sprawdzić przez ** TabName ** przy użyciu tego warunku 'if (e.Source to TabControl) '? –

+0

Moim zdaniem lepiej sprawdzić e.OriginalSource niż e.Source. –

Powiązane problemy