删除嵌套 TabPage 的代码并不总是有效
Code to delete a nested TabPage isn't always working
我想在我的应用程序上实现一个中间点击删除功能,就像大多数选项卡式环境所具有的那样:
它只是一个带有 TabControl
的单一表单,其中包含 2x TabPage
:ActiveItems 和 Archived Items。
这两个页面都包含自己的 TabControl
,用户可以根据需要添加任意数量的 TabPage
对象。
如果用户选择了活动项并删除了一个选项卡,则会删除正确的选项卡。如果他们从已归档项目中删除一个选项卡,它也会删除正确的选项卡。如果他们将一个选项卡从 Active 移动到 Archived 然后将其删除,则它删除了错误的选项卡。所以在上面的屏幕截图中,您看不到存档项目,但那里已经有 2 个选项卡。如果我将 13571 从 Active -> Archive 移动,然后将其删除(选项卡 #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
returns 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);
似乎它适用于我最初 post 中描述的用例,只需要最少的测试。但我 真的 想知道为什么 RemoveAt(tabIndex)
不起作用。
我想在我的应用程序上实现一个中间点击删除功能,就像大多数选项卡式环境所具有的那样:
它只是一个带有 TabControl
的单一表单,其中包含 2x TabPage
:ActiveItems 和 Archived Items。
这两个页面都包含自己的 TabControl
,用户可以根据需要添加任意数量的 TabPage
对象。
如果用户选择了活动项并删除了一个选项卡,则会删除正确的选项卡。如果他们从已归档项目中删除一个选项卡,它也会删除正确的选项卡。如果他们将一个选项卡从 Active 移动到 Archived 然后将其删除,则它删除了错误的选项卡。所以在上面的屏幕截图中,您看不到存档项目,但那里已经有 2 个选项卡。如果我将 13571 从 Active -> Archive 移动,然后将其删除(选项卡 #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
returns 2DeleteTab(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);
似乎它适用于我最初 post 中描述的用例,只需要最少的测试。但我 真的 想知道为什么 RemoveAt(tabIndex)
不起作用。