8

我需要确定用户在切换选项卡时来自哪个选项卡,并可能取消切换。我已经尝试过取消选择、取消选择、选择、选定事件,它们都显示 e.TabPageIndex 与 sender.SelectedIndex 相同。

是否有我可以使用的事件或属性,以便我可以确定这两个方面,或者我是否必须将某些东西从一个事件中缓存并在新事件中使用该值。

我试图避免处理 Deselecting/Deselected 事件并缓存要在 Selecting 事件中使用的值。我已经知道我可以做到这一点,所以我问是否有更清洁的方法,而不这样做。

我在 C# 和 VB 中都尝试过,结果相同(不足为奇)。

谢谢。

4

8 回答 8

10

看起来任何一个事件参数都不会包含前一个和当前选项卡的详细信息,因此您需要处理几个事件来跟踪。

至少,您需要使用该Deselected事件来存储对先前选择的选项卡的引用。您始终可以查询 TabControl 的当前选项卡。为了进一步扩展,您还可以处理Selected事件以跟踪当前选项卡。

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
于 2009-08-24T17:02:35.147 回答
2

您可以订阅TabControl.Deselecting。当它触发时,事件 args 中的选项卡索引将是旧索引。

然后,您可以订阅TabControl.Selected。当此事件触发时,选项卡索引将是新选择的选项卡的索引。

于 2009-08-24T16:58:47.370 回答
2

我相信选择事件中的 e.Cancel 标志应该做到这一点。这会在取消时将选定的选项卡发送回原始选项卡:

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

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

如果您确实需要更复杂的行为,则将选项卡控件子类化即可,然后覆盖 onSelecting 方法。这不应该掉以轻心。如果将来更改控件,您将破坏代码。并且您必须确认选项卡控件的所有行为都得到满足(即构造函数...)

编辑:根据反馈。这将在选择之前在内部跟踪原始选项卡。

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

}
于 2009-08-24T17:20:32.630 回答
1

您可以使用 Deselecting 事件获取用户正在离开的选项卡的索引,并将其存储在一个变量中以供以后使用:

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

您希望放置代码以防止在 Selecting 事件中切换。这是 VB.NET 中的一个示例,它将阻止您在选项卡控件上选择选项卡 2:

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
于 2009-08-24T17:05:44.377 回答
1

你可以做这样的事情:

    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
    }
于 2009-08-24T17:09:39.487 回答
1

为了提供我最初答案的替代方案....这是扩展 TabControl 的示例,它修改事件参数以包含更多详细信息。

免责声明这是一起拍的,肯定需要一些调整!

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

...以及使用此控件的示例表单...

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
于 2009-08-24T17:28:42.317 回答
1

tabControl 有一个非公共成员“lastSelection”,其中包含您想要的信息。不幸的是,我没有办法解决它。当他们拥有你想要的东西但不让你使用它时,这是非常令人沮丧的。

于 2013-04-02T17:25:40.757 回答
1

在 Deselect_Event 中试试这个:

private void tabControl1_Deselected(object sender, TabControlEventArgs e)
{
    var test = e.TabPage.Text;
}
于 2014-07-14T08:20:41.143 回答