private IList <MdiTab> AddNewTabs(IList <MdiTab> tabs, HashSet <Form> skipForms) { // RemoveClosedTabs should have gotten rid of any tabs with null AssociatedForms, // but filtering them out again just to be sure is safe and quick. Dictionary <Form, MdiTab> formToTabMap = tabs.Where(t => t.AssociatedForm != null).ToDictionary(tab => tab.AssociatedForm !); bool addedTabs = false; foreach (Form form in this.MdiChildren) { if (IsAvailable(form) && !skipForms.Contains(form) && !formToTabMap.TryGetValue(form, out MdiTab? tab)) { tab = new MdiTab(form); tab.Click += this.Tab_Click; tab.CloseClicked += this.Tab_CloseClicked; if (this.UseFormIconAsNewTabImage && form.Icon != null) { tab.Image = WindowsUtility.GetSmallIconImage(form.Icon); // Note: I originally set tab.ImageTransparentColor = Color.Transparent here, // but that made some white areas in the icons appear transparent even though // they shouldn't have been. That seems like a .NET bug since icons already // have explicitly transparent areas. } form.FormClosed += this.ChildForm_FormClosed; form.TextChanged += this.ChildForm_TextChanged; // Add it to the beginning like VS does. This keeps new tabs from immediately going // into the overflow area when lots of forms are open. This is also consistent with // how activating a tab from the overflow area moves it to the beginning of the tab list. this.Items.Insert(0, tab); addedTabs = true; } } // Update the tab list if any were added. IList <MdiTab> result = addedTabs ? this.GetTabs() : tabs; return(result); }
internal void BeginDragTimer(MdiTab tab) { if (!this.dragTimer.Enabled) { this.dragTab = tab; this.Capture = true; // This is slow enough that most normal, quick left clicks won't begin a drag // but fast enough that pressing and holding to begin a drag doesn't make // you wait an awkward amount of time. const int BeginDragMilliseconds = 200; // The drag timer ensures that normal, quick left clicks won't begin a drag, // which would change the cursor to a Move cursor. The default seems like a // good response time to me, but if the mouse hover time is quicker, then we'll // use that. Setting this on each timer usage allows us to react to system // setting changes. It also prevents us from getting a CA1601 code analysis // warning about mobility power management concerns with fast timers: // http://msdn.microsoft.com/en-us/library/ms182230.aspx this.dragTimer.Interval = Math.Min(BeginDragMilliseconds, SystemInformation.MouseHoverTime); this.dragTimer.Enabled = true; } }