public HelpBox ShowStage(HelpWorkflow workflow, HelpStage stage) { if (_currentHelpBox != null) { _host.Controls.Remove(_currentHelpBox); } _highlight = stage.HighlightControl; _currentHelpBox = new HelpBox(workflow, stage.HelpText, stage.OptionButtonText); _currentHelpBox.Location = stage.UseDefaultPosition ? GetGoodLocationForHelpBox(_currentHelpBox) : stage.HostLocationForStageBox; _host.Controls.Add(_currentHelpBox); _currentHelpBox.BringToFront(); _host.Invalidate(); return(_currentHelpBox); }
private Point GetGoodLocationForHelpBox(HelpBox currentHelpBox) { var screenCoordinates = _highlight.PointToScreen(new Point(0, 0)); var highlightTopLeft = _host.PointToClient(screenCoordinates); var highlightBottomLeft = new Point(highlightTopLeft.X, highlightTopLeft.Y + _highlight.ClientRectangle.Height); //First lets try to place it like this /**************HOST CONTROL BOUNDS************* * * HIGHLIGHT * HIGHLIGHT * MSG * *********************************************/ /**************HOST CONTROL BOUNDS************* * * HIGHLIGHT * _ HIGHLIGHT * ^ MSG<------availableSpaceHorizontally-> * | * V availableSpaceBelowHighlight *********************************************/ var availableSpaceBelowHighlight = _host.ClientRectangle.Height - highlightBottomLeft.Y; var availableSpaceHorizontally = _host.ClientRectangle.Width - highlightBottomLeft.X; //fallback var availableSpaceAboveHighlight = highlightTopLeft.Y; //there is enough space below if (currentHelpBox.Height < availableSpaceBelowHighlight) { if (_currentHelpBox.Width < availableSpaceHorizontally) { return(highlightBottomLeft); } //not enough space horizontally so try to move MSG to left till there is enough space /**************HOST CONTROL BOUNDS*********** * * HIGHLIGHT * <---|HIGHLIGHT * MSG_MSG_MSGMSG_MSG_MSGMSG_MSG_MSGMSG_MSG_MSG * *********************************************/ return(new Point(Math.Max(0, _host.ClientRectangle.Width - currentHelpBox.Width), highlightBottomLeft.Y)); } else if (currentHelpBox.Height < availableSpaceAboveHighlight) { //No space below so go above it if (_currentHelpBox.Width < availableSpaceHorizontally) { return(new Point(highlightTopLeft.X, highlightTopLeft.Y - currentHelpBox.Height)); } //consider moving X back because message box is so wide (See diagram above) return(new Point(Math.Max(0, _host.ClientRectangle.Width - currentHelpBox.Width), highlightTopLeft.Y - currentHelpBox.Height)); } var screenCoordinatesTopRight = _highlight.PointToScreen(new Point(_highlight.ClientRectangle.Width, 0)); var highlightTopRight = _host.PointToClient(screenCoordinatesTopRight); var spaceToLeft = highlightTopLeft.X; var spaceToRight = _host.ClientRectangle.Width - highlightTopRight.X; //there is no space at all for this help box (so just overlap it on the bottom left of the screen space available) if (spaceToRight < _currentHelpBox.Width && spaceToLeft < _currentHelpBox.Width) { return(new Point(0, _host.ClientRectangle.Height - _currentHelpBox.Height)); } //there is space to the right or left so put it in whichever is greater if (spaceToRight > spaceToLeft) { return(highlightTopRight); } return(new Point(highlightTopLeft.X - _currentHelpBox.Width, 0)); }