2009-08-24 10 views
7

Muszę określić, z której karty pochodzi użytkownik, i przejść do niego, kiedy przełączają karty i ewentualnie anulować przełącznik. Próbowałem Odznaczam, Odznaczałem, Wybieram, Wybrane zdarzenia, a wszystkie z nich pokazują, że e.TabPageIndex jest taki sam jak sender.SelectedIndex.Jak określić, z której karty przechodzisz z/do elementu sterującego zakładki WinForm?

Czy istnieje zdarzenie, lub właściwość, której mogę użyć, aby móc określić obie strony tego, lub czy muszę zhakować coś razem z buforowaniem go z jednego zdarzenia i użyciem tej wartości w nowym zdarzeniu.

Próbuję uniknąć obsługi zdarzeń Odznacz/Odznacz i buforowanie wartości do użycia w zdarzeniu Wybór. Wiem już, że mogę to zrobić, więc pytam, czy istnieje czystszy sposób, bez robienia tego.

Próbowałem w obu C# i VB, z tymi samymi wynikami (bez zaskoczenia).

Dzięki.

Odpowiedz

7

Nie wygląda na to, aby jakikolwiek argument dotyczący jednego zdarzenia zawierał szczegóły zarówno poprzednich, jak i bieżących kart, więc musisz zarządzać kilkoma zdarzeniami, aby śledzić.

Co najmniej trzeba użyć zdarzenia Deselected, aby zapisać odniesienie do poprzednio wybranej karty. Zawsze możesz wysłać zapytanie do TabControl do bieżącej zakładki. Aby nieco się rozciągnąć, możesz także obsługiwać zdarzenie Selected, aby śledzić bieżącą kartę.

Option Strict On 
Option Explicit On 

Public Class Form1 

    Private PreviousTab As TabPage 
    Private CurrentTab As TabPage 

    Private Sub TabControl1_Deselected(ByVal sender As Object, ByVal e As System.Windows.Forms.TabControlEventArgs) Handles TabControl1.Deselected 
     PreviousTab = e.TabPage 
     Debug.WriteLine("Deselected: " + e.TabPage.Name) 
    End Sub 

    Private Sub TabControl1_Selected(ByVal sender As Object, ByVal e As System.Windows.Forms.TabControlEventArgs) Handles TabControl1.Selected 
     CurrentTab = e.TabPage 
     Debug.WriteLine("Selected: " + e.TabPage.Name) 
    End Sub 

    Private Sub TabControl1_Selecting(ByVal sender As Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles TabControl1.Selecting 
     If CurrentTab Is Nothing Then Return 
     Debug.WriteLine(String.Format("Proposed change from {0} to {1}", CurrentTab.Name, e.TabPage.Name)) 
    End Sub 

End Class 
+0

Tak, to jest rozwiązanie, które mam, ale staram się tego uniknąć. Ponadto muszę użyć zdarzenia Wybieranie, aby można było anulować, ale to nie ma znaczenia. –

+0

@Rick: Nie wygląda na to, że WinForms TabControl obsługuje wszystko, czego szukasz, możesz go rozszerzyć, aby podać informacje, których szukasz, lub możesz użyć TabControl innej firmy (myślę, że Infragistics wspiera twoje zachowanie "Patrząc na) – STW

1

Możesz subskrybować TabControl.Deselecting. Po uruchomieniu indeks tab w argach zdarzenia będzie starym indeksem.

Możesz następnie zasubskrybować numer TabControl.Selected. Po uruchomieniu tego zdarzenia indeks tab będzie indeksem nowo wybranej karty.

+0

Tak, staram się uniknąć konieczności buforować wartość takiego. Wygląda jednak, jakby to była jedyna droga. –

+0

Tak. Nie ma jednego zdarzenia, które niestety ma dostępne oba indeksy tabulatorów. –

1

można uzyskać indeks zakładce użytkownik oddala się od ze zdarzeniem odznaczając i przechowywać ją w zmiennej do późniejszego użytku:

Private Sub TabControl1_Deselecting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles TabControl1.Deselecting 
    someClassLevelVariable = e.TabPageIndex 
End Sub 

Chcesz kod umieścić, aby zapobiec przełącznik w przypadku wyboru. Oto przykład, w VB.NET, który uniemożliwi wybierając kartę 2 na kontrolę zakładka:

Private Sub TabControl1_Selecting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles TabControl1.Selecting 
    If (e.TabPageIndex = 1) Then 
     e.Cancel = True 
    End If 
End Sub 
+0

To jednak nie pomaga, ponieważ chcę poznać poprzednią kartę, zanim zdecyduję, czy anulować, czy nie. –

+0

Zaktualizowałem moją odpowiedź, ale potem przeczytałem w innym komentarzu, że nie chcesz, aby buforować wartość bieżącej karty. Nie znam innego sposobu. – raven

1

mógłby zrobić coś takiego:

private int _oldIndex = -1; 

    private void tabControl1_Deselected(object sender, TabControlEventArgs e) 
    { 
     _oldIndex = e.TabPageIndex; 
    } 

    private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e) 
    { 
     if (_oldIndex != -1) 
     { 
      if (CanChangeTab(_oldIndex, e.TabPageIndex)) 
      { 
       e.Cancel = true; 
      } 
     } 
    } 

    private bool CanChangeTab(int fromIndex, int toIndex) 
    { 
     // Put your logic here 
    } 
2

wierzę flagę e.Cancel w wybranie zdarzenia powinno wykonać tę sztuczkę. Ten wysyła wybraną kartę z powrotem do oryginału na anulowanie:

private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e) 
    { 
     int badIndex = 0; 

     if (tabControl1.SelectedIndex == badIndex) 
      e.Cancel = true;    
    } 

Jeśli naprawdę potrzebujesz bardziej złożonego beharvior, instacji kontroli zakładka będzie działać, następnie zastąpić metodę onSelecting. Nie należy tego robić lekko. Jeśli kontrola zostanie zmieniona w przyszłości, będziesz mieć złamany kod. I musisz potwierdzić, że wszystkie zachowanie sterowania kartą są spełnione (tj. Konstruktorzy ...)

EDYTOWANIE: na podstawie opinii. Spowoduje to wewnętrzne prześledzenie oryginalnej zakładki przed wyborem.

public class MyTab : System.Windows.Forms.TabControl 
{ 
    int _previousTab; 

    protected override void OnSelecting(TabControlCancelEventArgs e) 
    { 
     // Some logic here to do cool UI things, perhaps use _previousTab 

     // Call the base method 
     base.OnSelecting(e);   
    } 
    protected override void OnDeselecting(TabControlCancelEventArgs e) 
    { 
     // Store the value for use later in the chain of events 
     _previousTab = this.SelectedIndex; 

     // Call the base method 
     base.OnDeselecting(e); 
    } 

} 
+0

To nic nie zmienia, jeśli chodzi o rzeczywisty problem, gdzie muszę wiedzieć, z której karty pochodzi. Dziedziczenie z kontroli również nie naprawi problemu, niestety. –

1

Aby zapewnić alternatywę dla mojej początkowej odpowiedzi ....oto przykład rozszerzonego TabControl, który modyfikuje argumenty zdarzeń, aby zawierały więcej szczegółów.

Zrzeczenie się odpowiedzialności To jest spolszczone, na pewno będzie wymagało pewnych korekt!

Option Strict On 
Option Explicit On 

Imports System 
Imports System.Windows.Forms 

Public Class ExtendedTabControl 
    Inherits TabControl 

    Public Shadows Event Selecting As EventHandler(Of SelectedTabChangingEventArgs) 
    Public Shadows Event Selected As EventHandler(Of SelectedTabChangedEventArgs) 

    Private _PreviousTab As TabPage 
    Public Property PreviousTab() As TabPage 
     Get 
      Return _PreviousTab 
     End Get 
     Private Set(ByVal value As TabPage) 
      _PreviousTab = value 
     End Set 
    End Property 

    Private _CurrentTab As TabPage 
    Public Property CurrentTab() As TabPage 
     Get 
      Return _CurrentTab 
     End Get 
     Private Set(ByVal value As TabPage) 
      _CurrentTab = value 
     End Set 
    End Property 

    Protected Overrides Sub OnDeselected(ByVal e As System.Windows.Forms.TabControlEventArgs) 
     PreviousTab = e.TabPage 
     MyBase.OnDeselected(e) 
    End Sub 

    Protected Overrides Sub OnSelected(ByVal e As System.Windows.Forms.TabControlEventArgs) 
     CurrentTab = e.TabPage 
     Dim selectedArgs As New SelectedTabChangedEventArgs(e, PreviousTab) 
     RaiseEvent Selected(Me, selectedArgs) 
    End Sub 

    Protected Overrides Sub OnSelecting(ByVal e As System.Windows.Forms.TabControlCancelEventArgs) 
     Dim selectedArgs As New SelectedTabChangingEventArgs(e, CurrentTab) 
     RaiseEvent Selecting(Me, selectedArgs) 
    End Sub 

End Class 

Public Class SelectedTabChangingEventArgs 
    Inherits TabControlCancelEventArgs 

    Public Sub New(ByVal selectingEventArgs As TabControlCancelEventArgs, ByVal previousTabPage As TabPage) 
     MyBase.New(selectingEventArgs.TabPage, selectingEventArgs.TabPageIndex, selectingEventArgs.Cancel, selectingEventArgs.Action) 
     Me.CurrentTab = previousTabPage 
    End Sub 

    Private _CurrentTab As TabPage 
    Public Property CurrentTab() As TabPage 
     Get 
      Return _CurrentTab 
     End Get 
     Set(ByVal value As TabPage) 
      _CurrentTab = value 
     End Set 
    End Property 

End Class 

Public Class SelectedTabChangedEventArgs 
    Inherits TabControlEventArgs 

    Public Sub New(ByVal selectedEventArgs As TabControlEventArgs, ByVal previousTabPage As TabPage) 
     MyBase.New(selectedEventArgs.TabPage, selectedEventArgs.TabPageIndex, selectedEventArgs.Action) 
     Me.PreviousTab = previousTabPage 
    End Sub 

    Private _PreviousTab As TabPage 
    Public Property PreviousTab() As TabPage 
     Get 
      Return _PreviousTab 
     End Get 
     Set(ByVal value As TabPage) 
      _PreviousTab = value 
     End Set 
    End Property 

End Class 

... i Form próbki za pomocą tej kontroli ...

Option Strict On 
Option Explicit On 

Public Class Form1 

    Private Sub TabControl1_Selecting(ByVal sender As Object, ByVal e As SelectedTabChangingEventArgs) Handles TabControl1.Selecting 
     If e.CurrentTab Is Nothing Then Return 
     Console.WriteLine(String.Format("Proposed change from {0} to {1}", e.CurrentTab.Name, e.TabPage.Name)) 
    End Sub 

    Private Sub TabControl1_Selected(ByVal sender As Object, ByVal e As SelectedTabChangedEventArgs) Handles TabControl1.Selected 
     Console.WriteLine(String.Format("Changed from {0} to {1}", e.PreviousTab.Name, e.TabPage.Name)) 
    End Sub 

End Class 
+0

Niestety, nie mogę śledzić zdarzeń, ponieważ jest przekazywany jako System.Windows.Forms.Tabcontrol w inne metody. Doceniam odpowiedzi, ale wygląda na to, że moja początkowa decyzja była prawidłowa. –

+0

@Rick: To * może * nadal działa, ponieważ typy zacienionych zdarzeń rozszerzają typy używane przez typ bazowy; metody, które działają z nim jako TabControl, nie widziałyby dodatkowych właściwości. – STW

+0

Kod, w którym jest używany, jest ramą do obsługi innych programistów, więc jestem trochę ograniczony w tym, co mogę zrobić bez łamania istniejącego kodu. Jeszcze raz dziękuję za odpowiedzi. –

1

TabControl ma człon niepubliczne "lastSelection", że ma informacje, które chcesz. Niestety nie widzę sposobu, aby do tego dojść. To bardzo frustrujące, kiedy mają to, czego chcesz, ale nie pozwalają ci z niego korzystać.

1

Spróbuj tego w Deselect_Event:

private void tabControl1_Deselected(object sender, TabControlEventArgs e) 
{ 
    var test = e.TabPage.Text; 
} 
Powiązane problemy