/// <summary> /// Launch the PopupTree. /// Typical usage, where 'this' is a control that the list should appear below: /// m_listBox.Launch(Parent.RectangleToScreen(Bounds), Screen.GetWorkingArea(this)); /// Or, where rect is a rectangle in the client area of control 'this': /// m_listBox.Launch(RectangleToScreen(rect), Screen.GetWorkingArea(this); /// (Be sure to set the height and width of the PopupTree first.) /// </summary> /// <param name="launcherBounds">A rectangle in 'screen' coordinates indicating where to display the list. Typically, as shown /// above, the location of something the user clicked to make the list display. It's significance is that /// the tree will usually be shown with its top left just to the right of the bottom left of the rectangle, and /// (if the tree width has not already been set explicitly) its width will match the rectangle. If there is not /// room to display the tree below this rectangle, it will be displayed above instead.</param> /// <param name="screenBounds">A rectangle in 'screen' coordinates indicating the location of the actual screen /// that the tree is to appear on.</param> public void Launch(Rectangle launcherBounds, Rectangle screenBounds) { CheckDisposed(); //Figure where to put it. First try right below the main combo box. // Pathologically the list box may be bigger than the available height. If so shrink it. int maxListHeight = Math.Max(launcherBounds.Top - screenBounds.Top, screenBounds.Bottom - launcherBounds.Bottom); if (Height > maxListHeight) { Height = maxListHeight; } // This is the default position right below the launcherBounds. Rectangle popupBounds = new Rectangle(launcherBounds.Left, launcherBounds.Bottom, this.Width, this.Height); if (screenBounds.Bottom < popupBounds.Bottom) { // extends below the bottom of the screen. Use a rectangle above instead. // We already made sure it will fit in one place or the other. popupBounds = new Rectangle(launcherBounds.Left, launcherBounds.Top - this.Height, this.Width, this.Height); } if (screenBounds.Right < popupBounds.Right) { // Extends too far to the right; adjust (amount is negative to move left). popupBounds.Offset(screenBounds.Right - popupBounds.Right, 0); } if (screenBounds.Left > popupBounds.Left) { // Extends too far to the left; adjust (amount is positive to move right). popupBounds.Offset(screenBounds.Left - popupBounds.Left, 0); } this.Location = new Point(popupBounds.Left, popupBounds.Top); // Once the launching form has been set, it should never need to be changed. // See FWNX-748 for an example of things going wrong (at least on Mono). if (m_launchForm == null) { m_launchForm = Form.ActiveForm; } Debug.Assert(m_launchForm != this); #if __MonoCS__ // FWNX-520: avoid a weird mono problem this.Show(m_launchForm); #else this.Show(); #endif m_fShown = true; TreeNode selNode = m_treeView.SelectedNode; if (selNode != null) { selNode.EnsureVisible(); } m_fwPopupMessageFilter = new FwPopupMessageFilter(this); Application.AddMessageFilter(m_fwPopupMessageFilter); m_treeView.Focus(); // Enhance JohnT: maybe should do something to ensure that, if there's a // selected node, things expand and scroll to show it. }
// Remove your message filter, typically prior to hiding, or because we got hidden. internal void RemoveFilter() { CheckDisposed(); if (m_fwPopupMessageFilter != null) { Application.RemoveMessageFilter(m_fwPopupMessageFilter); m_fwPopupMessageFilter.Dispose(); m_fwPopupMessageFilter = null; } }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { System.Diagnostics.Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); // Must not be run more than once. if (IsDisposed) { return; } if (disposing) { RemoveFilter(); // Disposes m_fwPopupMessageFilter, among other things. if (m_treeView != null) { EnableAfterAndBeforeSelectHandling(false); if (!Platform.IsMono) { // FWNX-399 m_treeView.MouseDown -= new MouseEventHandler(m_treeView_MouseDown); m_treeView.MouseUp -= new MouseEventHandler(m_treeView_MouseUp); } m_treeView.KeyDown -= new KeyEventHandler(m_treeView_KeyDown); if (!Controls.Contains(m_treeView)) { m_treeView.Dispose(); } } if (components != null) { components.Dispose(); } } m_fwPopupMessageFilter = null; m_treeView = null; m_tnMouseDown = null; // m_selectedNodeAction = null; // Can't null it, since it is a value type. m_tabStopControl = null; base.Dispose(disposing); }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { //Debug.WriteLineIf(!disposing, "****************** " + GetType().Name + " 'disposing' is false. ******************"); // Must not be run more than once. if (IsDisposed) { return; } if (disposing) { RemoveFilter(); // Disposes m_fwPopupMessageFilter, among other things. if (m_treeView != null) { m_treeView.AfterSelect -= new TreeViewEventHandler(m_treeView_AfterSelect); m_treeView.BeforeSelect -= new TreeViewCancelEventHandler(m_treeView_BeforeSelect); m_treeView.MouseDown -= new MouseEventHandler(m_treeView_MouseDown); m_treeView.MouseUp -= new MouseEventHandler(m_treeView_MouseUp); m_treeView.KeyDown -= new KeyEventHandler(m_treeView_KeyDown); if (!Controls.Contains(m_treeView)) { m_treeView.Dispose(); } } if (components != null) { components.Dispose(); } } m_fwPopupMessageFilter = null; m_treeView = null; m_tnMouseDown = null; // m_selectedNodeAction = null; // Can't null it, since it is a value type. m_tabStopControl = null; base.Dispose(disposing); }
/// <summary> /// Launch the PopupTree. /// Typical usage, where 'this' is a control that the list should appear below: /// m_listBox.Launch(Parent.RectangleToScreen(Bounds), Screen.GetWorkingArea(this)); /// Or, where rect is a rectangle in the client area of control 'this': /// m_listBox.Launch(RectangleToScreen(rect), Screen.GetWorkingArea(this); /// (Be sure to set the height and width of the PopupTree first.) /// </summary> /// <param name="launcherBounds">A rectangle in 'screen' coordinates indicating where to display the list. Typically, as shown /// above, the location of something the user clicked to make the list display. It's significance is that /// the tree will usually be shown with its top left just to the right of the bottom left of the rectangle, and /// (if the tree width has not already been set explicitly) its width will match the rectangle. If there is not /// room to display the tree below this rectangle, it will be displayed above instead.</param> /// <param name="screenBounds">A rectangle in 'screen' coordinates indicating the location of the actual screen /// that the tree is to appear on.</param> public void Launch(Rectangle launcherBounds, Rectangle screenBounds) { CheckDisposed(); //Figure where to put it. First try right below the main combo box. // Pathologically the list box may be bigger than the available height. If so shrink it. int maxListHeight = Math.Max(launcherBounds.Top - screenBounds.Top, screenBounds.Bottom - launcherBounds.Bottom); if (Height > maxListHeight) Height = maxListHeight; // This is the default position right below the launcherBounds. Rectangle popupBounds = new Rectangle(launcherBounds.Left, launcherBounds.Bottom, this.Width, this.Height); if (screenBounds.Bottom < popupBounds.Bottom) { // extends below the bottom of the screen. Use a rectangle above instead. // We already made sure it will fit in one place or the other. popupBounds = new Rectangle(launcherBounds.Left, launcherBounds.Top - this.Height, this.Width, this.Height); } if (screenBounds.Right < popupBounds.Right) { // Extends too far to the right; adjust (amount is negative to move left). popupBounds.Offset(screenBounds.Right - popupBounds.Right, 0); } if (screenBounds.Left > popupBounds.Left) { // Extends too far to the left; adjust (amount is positive to move right). popupBounds.Offset(screenBounds.Left - popupBounds.Left, 0); } this.Location = new Point(popupBounds.Left, popupBounds.Top); // Once the launching form has been set, it should never need to be changed. // See FWNX-748 for an example of things going wrong (at least on Mono). if (m_launchForm == null) m_launchForm = Form.ActiveForm; Debug.Assert(m_launchForm != this); #if __MonoCS__ // FWNX-520: avoid a weird mono problem this.Show(m_launchForm); #else this.Show(); #endif m_fShown = true; TreeNode selNode = m_treeView.SelectedNode; if (selNode != null) selNode.EnsureVisible(); m_fwPopupMessageFilter = new FwPopupMessageFilter(this); Application.AddMessageFilter(m_fwPopupMessageFilter); m_treeView.Focus(); // Enhance JohnT: maybe should do something to ensure that, if there's a // selected node, things expand and scroll to show it. }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { System.Diagnostics.Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); // Must not be run more than once. if (IsDisposed) return; if (disposing) { RemoveFilter(); // Disposes m_fwPopupMessageFilter, among other things. if (m_treeView != null) { EnableAfterAndBeforeSelectHandling(false); #if !__MonoCS__ // FWNX-399 m_treeView.MouseDown -= new MouseEventHandler(m_treeView_MouseDown); m_treeView.MouseUp -= new MouseEventHandler(m_treeView_MouseUp); #endif m_treeView.KeyDown -= new KeyEventHandler(m_treeView_KeyDown); if (!Controls.Contains(m_treeView)) m_treeView.Dispose(); } if(components != null) { components.Dispose(); } } m_fwPopupMessageFilter = null; m_treeView = null; m_tnMouseDown = null; // m_selectedNodeAction = null; // Can't null it, since it is a value type. m_tabStopControl = null; base.Dispose( disposing ); }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { //Debug.WriteLineIf(!disposing, "****************** " + GetType().Name + " 'disposing' is false. ******************"); // Must not be run more than once. if (IsDisposed) return; if (disposing) { RemoveFilter(); // Disposes m_fwPopupMessageFilter, among other things. if (m_treeView != null) { m_treeView.AfterSelect -= new TreeViewEventHandler(m_treeView_AfterSelect); m_treeView.BeforeSelect -= new TreeViewCancelEventHandler(m_treeView_BeforeSelect); m_treeView.MouseDown -= new MouseEventHandler(m_treeView_MouseDown); m_treeView.MouseUp -= new MouseEventHandler(m_treeView_MouseUp); m_treeView.KeyDown -= new KeyEventHandler(m_treeView_KeyDown); if (!Controls.Contains(m_treeView)) m_treeView.Dispose(); } if(components != null) { components.Dispose(); } } m_fwPopupMessageFilter = null; m_treeView = null; m_tnMouseDown = null; // m_selectedNodeAction = null; // Can't null it, since it is a value type. m_tabStopControl = null; base.Dispose( disposing ); }