Reputation: 817
I need to determine which tab the user is coming from, and going to, when they switch tabs, and possibly cancel the switch. I have tried the Deselecting, Deselected, Selecting, Selected events, and all of them show the e.TabPageIndex to be the same as the sender.SelectedIndex.
Is there an event, or property, that I can use so that I can determine both sides of this, or do I have to hack something together with caching it from one event and using that value in the new event.
I am trying to avoid handling the Deselecting/Deselected events and caching the value to use in the Selecting event. I already know I can do this, so I am asking if there is a cleaner way, without doing this.
I have tried in both C# and VB, with the same results (no surprise).
Thanks.
Upvotes: 9
Views: 13348
Reputation: 31
Try this in Deselect_Event:
private void tabControl1_Deselected(object sender, TabControlEventArgs e)
{
var test = e.TabPage.Text;
}
Upvotes: 1
Reputation: 46366
It doesn't look like any one event argument will carry the details of both the previous and current tabs, so you'll need to handle a couple of events to keep track.
At a minimum, you'd need to use the Deselected
event to store a reference to the previously-selected tab. You can always query the TabControl for its current tab. To stretch a little further, you can also handle the Selected
event to track the current tab.
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
Upvotes: 11
Reputation: 11
The tabControl has a non-public member "lastSelection" that has the info you want. Unfortunately, I don't see a way to get to it. It's very frustrating when they have what you want but don't let you use it.
Upvotes: 1
Reputation: 127
I believe the e.Cancel flag in the selecting event should do this trick. This sends the selected tab back to the original on cancel:
private void tabControl1_Selecting( object sender, TabControlCancelEventArgs e )
{
int badIndex = 0;
if ( tabControl1.SelectedIndex == badIndex )
e.Cancel = true;
}
If you really need more complex beharvior, subclassing the tab control will work, Then override the onSelecting method. This shouldn't be done lightly. If the control is changed in the future you will have broken code. And you have to confirm that all the behavior of the tab control are met (ie constructors ...)
EDIT: based on feedback. This will internally track the original tab before selection.
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 );
}
}
Upvotes: 2
Reputation: 46366
To provide an alternative to my initial answer.... here's a sample of an extended TabControl which modifies the event arguments to include some more details.
Disclaimer This is slapped together, it'll need some adjustments for sure!
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
...and a sample Form using this control...
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
Upvotes: 1
Reputation: 18125
You can get the index of the tab the user is moving away from with the Deselecting event and store it in a variable for later use:
Private Sub TabControl1_Deselecting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles TabControl1.Deselecting
someClassLevelVariable = e.TabPageIndex
End Sub
You want put code to prevent the switch in the Selecting event. Here's an example in VB.NET that will prevent you from selecting tab 2 on a tab control:
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
Upvotes: 1
Reputation: 292365
You could do something like that :
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
}
Upvotes: 1
Reputation: 564333
You can subscribe to TabControl.Deselecting. When it fires, the tab index in the event args will be the old index.
You can then subscribe to TabControl.Selected. When this event fires, the tab index will be the index of the newly selected tab.
Upvotes: 2