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

标签 c# .net winforms tabcontrol tabpage

我想在我的应用程序上实现一个 MiddleClick-To-Delete 功能,就像大多数选项卡式环境一样:

enter image description here

它只是一个带有 TabControl 的单一表单,它有 2x TabPage:ActiveItems 和 Archived Items。

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

如果用户选择了事件项并删除了一个选项卡,则会删除正确的选项卡。如果他们从已归档项目中删除一个选项卡,它也会删除正确的选项卡。如果他们将一个选项卡从 Active 移动到 Archived 然后将其删除,则它删除了错误的选项卡。所以在上面的屏幕截图中,您看不到存档项目,但那里已经有 2 个选项卡。如果我从 Active -> Archive 移动 13571,然后将其删除(选项卡 #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# - 删除嵌套 TabPage 的代码并不总是有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31457372/

相关文章:

c# - Asp.Net Ajax WebService 和内部错误 500

c# - 如何设置命令的路径

c# - 使用数据库、C# Windows 窗体应用程序存储和检索颜色

winforms - 将按钮项添加到 WinForm 时,KeyDown 事件监听器似乎不起作用

c# - 对表达式树使用 lambda 返回值

c# - 从 Control 派生但隐藏属性

c# - 以编程方式启用/禁用硬件设备

Java .Net 互操作。 Axis java.util.Map

.net - 如何绑定(bind) WinForm 文本框以在 TextChanged 而不是 LostFocus 上更新

c# - 在 C# 中从 TabControl 中删除 tabPage 时引发什么事件