Frage Wie kann ich feststellen, auf welchem ​​Tab in ein WinForms-Registersteuerelement verschoben wird?


Ich muss feststellen, aus welcher Registerkarte der Benutzer kommt und wann er sie wechselt, wenn sie die Registerkarten wechseln und möglicherweise den Schalter abbrechen. Ich habe versucht, das Abwählen, Abwählen, Auswählen, Ausgewählte Ereignisse, und alle von ihnen zeigen die e.TabPageIndex identisch mit dem Sender.SelectedIndex.

Gibt es ein Ereignis oder eine Eigenschaft, die ich verwenden kann, damit ich beide Seiten bestimmen kann, oder muss ich etwas zusammenhacken, indem ich es von einem Ereignis zwischenspeichern und diesen Wert im neuen Ereignis verwenden kann?

Ich versuche zu vermeiden, die Deselecting / Deselected-Ereignisse zu behandeln und den Wert zu speichern, der in dem Selecting-Ereignis verwandt wird. Ich weiß bereits, dass ich das tun kann, also frage ich, ob es einen saubereren Weg gibt, ohne dies zu tun.

Ich habe sowohl in C # als auch in VB versucht, mit den gleichen Ergebnissen (keine Überraschung).

Vielen Dank.


7
2017-08-24 16:43


Ursprung


Antworten:


Es sieht nicht so aus, als ob irgendein Ereignisargument die Details sowohl der vorherigen als auch der aktuellen Registerkarte enthält. Sie müssen also einige Ereignisse behandeln, um den Überblick zu behalten.

Zumindest müssten Sie die verwenden Deselected Ereignis, um einen Verweis auf die zuvor ausgewählte Registerkarte zu speichern. Sie können das TabControl immer nach seiner aktuellen Registerkarte abfragen. Um etwas weiter zu gehen, können Sie auch die Selected Ereignis, um den aktuellen Tab zu verfolgen.

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

8
2017-08-24 17:02



Ich glaube, dass das e.Cancel-Flag in dem auswählenden Ereignis diesen Trick tun sollte. Dies sendet die ausgewählte Registerkarte beim Abbrechen zurück an das Original:

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

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

Wenn Sie wirklich komplexeres Behavior benötigen, funktioniert das Erstellen von Unterklassen des Tab-Steuerelements. Überschreiben Sie dann die OnSelecting-Methode. Dies sollte nicht leichtfertig getan werden. Wenn das Steuerelement in der Zukunft geändert wird, haben Sie Code beschädigt. Und Sie müssen bestätigen, dass das gesamte Verhalten des Registersteuerelements erfüllt ist (dh Konstruktoren ...)

BEARBEITEN: basierend auf Feedback. Dies wird die ursprüngliche Registerkarte vor der Auswahl intern verfolgen.

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 );
    }

}

2
2017-08-24 17:20



Sie können abonnieren TabControl.Deselecting. Wenn es ausgelöst wird, ist der Registerindex in den Ereignisargumenten der alte Index.

Sie können dann abonnieren TabControl.Selected. Wenn dieses Ereignis ausgelöst wird, ist der Registerkartenindex der Index der neu ausgewählten Registerkarte.


1
2017-08-24 16:58



Du könntest so etwas machen:

    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
    }

1
2017-08-24 17:09



Sie können den Index der Registerkarte, von der sich der Benutzer entfernt, mit dem Deselecting-Ereignis abrufen und in einer Variablen zur späteren Verwendung speichern:

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

Sie möchten Put-Code, um den Schalter im Selecting-Event zu verhindern. Hier ein Beispiel in VB.NET, das verhindert, dass Sie Tab 2 auf einem Tab-Steuerelement auswählen:

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

1
2017-08-24 17:05



Um eine Alternative zu meiner ersten Antwort zu bieten .... hier ist ein Beispiel für ein erweitertes TabControl, welches die Event-Argumente um einige Details erweitert.

Haftungsausschluss Dies ist zusammen geschlagen, es wird sicher einige Anpassungen benötigen!

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

... und ein Beispielformular mit diesem Steuerelement ...

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

1
2017-08-24 17:28



Die Registerkarte Steuerelement hat ein nicht öffentliches Mitglied "lastSelection" mit den gewünschten Informationen. Leider sehe ich keinen Weg dahin. Es ist sehr frustrierend, wenn sie haben, was Sie wollen, aber lassen Sie es nicht benutzen.


1
2018-04-02 17:25



Versuchen Sie dies in Deselect_Event:

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

1
2017-07-14 08:20