删除嵌套的TabPage的代码并不总是有效

我想在我的应用程序中像大多数选项卡式环境一样实现MiddleClick-To-Delete功能,如下所示:

它是一个具有2个TabPage的TabControl的单一表单:ActiveItems和Archived Items.

这两个页面都包含自己的TabControl,用户可以根据需要添加任意数量的TabPage对象.

如果用户选择了“活动项目”,并且他们删除了一个选项卡,则它将删除正确的选项卡.如果他们从“存档的项目”中删除了一个标签,它也会删除正确的标签.如果他们将选项卡从“活动”移动到“已存档”,然后将其删除,则表示删除了错误的选项卡.因此,在上面的屏幕截图中,您看不到“已归档的项目”,但是已经有2个标签.如果我将13571从Active移至->存档,然后将其删除(标签#3,索引#2),然后删除标签#2,索引#1.

// Both the tcActive and tcArchived, the TabControls on tcRoot's two Active Items
// and Archived Items tab pages, subscribe to this event
private void tc_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button != System.Windows.Forms.MouseButtons.Left)
        tabPageClicked = e.Location;

    if (e.Button == MouseButtons.Middle)
        DeleteTab();
}

// Passes the TabControl and TabPageIndex to be deleted
private void DeleteTab()
{
    int tpi = GetTabIndex(tabPageClicked);

    if (tcActiveArchive.SelectedIndex.Equals(0))
        DeleteTab(tcActive, tpi);
    else
        DeleteTab(tcArchived, tpi);
}

// Gets the TabPage index from either Active Items page or Archived Items page
private int GetTabIndex(Point p)
{
    if (tcActiveArchive.SelectedIndex.Equals(0))
        return tcActive.TabPages.IndexOf(tcActive.TabPages.Cast<TabPage>().Where((t, i) => tcActive.GetTabRect(i).Contains(p)).First());
    else
        return tcArchived.TabPages.IndexOf(tcArchived.TabPages.Cast<TabPage>().Where((t, i) => tcArchived.GetTabRect(i).Contains(p)).First());
}

// Actual removal of TabPage at index tabIndex from TabControl tc
private void DeleteTab(TabControl tc, int tabIndex)
{
    lastDeleteWasActiveTab = (tcActiveArchive.SelectedIndex.Equals(0));

    //Tab object just stores a string, string[] and bool
    Tab deletedTab = new Tab(tc.TabPages[tabIndex].Text, ((TextBox)tc.TabPages[tabIndex].Controls[0]).Lines, lastDeleteWasActiveTab);

    if (lastDeleteWasActiveTab)
    {
        deletedActiveTabs.Push(deletedTab);
        filesToDelete.Add(mantisDir + tc.TabPages[tabIndex].Text + ".txt");
    }
    else
    {
        deletedArchiveTabs.Push(deletedTab);
        filesToDelete.Add(archiveDir + tc.TabPages[tabIndex].Text + ".txt");
    }

    tc.TabPages.RemoveAt(tabIndex);

    //Try to select the tab to the right of the one that was deleted
    if (tc.TabPages.Count >= tabIndex + 1) 
        tc.SelectedIndex = tabIndex;
    else
        tc.SelectedIndex = tabIndex - 1;

    undoQueue.Push((lastDeleteWasActiveTab) ? UndoEventType.DeleteActive : UndoEventType.DeleteArchive);
}

逐步解决上述情况的代码:

> MouseDown事件触发
> DeleteTab()
> GetTabIndex返回2
> DeleteTab(tcArchived,2);叫做
> Tab DeletedTab具有应包含的所有值,表明我们在看正确的TabPage /索引.
> tc.RemoveAt(2)被调用

但是,它删除了第二项,而不是索引2.绝对无法找出问题所在.

解决方法:

更改此行:

DeleteTab(TabControl tc, int tabIndex)
{
    //other code
    tc.TabPages.RemoveAt(tabIndex);
}

至:

TabPage tp = tc.TabPages[tabIndex];
tc.TabPages.Remove(tp);

似乎可以用我的原始文章中描述的用例进行工作,而无需进行最少的测试.但是我真的很想知道为什么RemoveAt(tabIndex)无法正常工作.

上一篇:C# WPF可拖拽的TabControl


下一篇:为什么在XAML TabControl的选项卡内容区域中显示选项卡标题?