Version 9.1
I'm using a ToolTip to display the full text of a trimmed UltraFormattedLinkLabel in a mock-up application I'm working on. I've used this code before on simpler forms, and it displays correctly. This form, which has a link label in a panel that's docked on the left via an UltraDockManager. In this case, as the attached picture shows, it's way off. Here's the code I'm using:
private void link_MouseHover( object sender, EventArgs e ) { var lbl = (UltraFormattedLinkLabel) sender; var ui = lbl.UIElement.GetDescendant( typeof( FormattedLinkEmbeddableUIElement ) ) as FormattedLinkEmbeddableUIElement; if( ui == null || ui.IsDataFullyVisible ) return; var tt = new ToolTip( lbl ) { DisplayStyle = ToolTipDisplayStyle.BalloonTip, ToolTipText = lbl.Value.ToString( ) }; var loc = this.PointToScreen( lbl.Location ); tt.Show( new Point( loc.X, loc.Y + lbl.Height ) ); }
Is there something I need to do differently here?
My guess here is that the label's Location is based relative to its parent, not the form itself, so you should be using the PointToScreen method on the parent instead of the form.
-Matt
Do you mean this:
var loc = lbl.Parent.PointToScreen( this.Location );
That doesn't work, either, and leads to inconsistent results. When the form is maximized, it shows in approximately the same position as before, but off to the left (I have it maximized on my right-hand monitor). If the form is not maximized, it ends up somewhat near the middle of the form.
I just tried this out in a sample project and could experience what you're seeing. I think that you need to walk up the parent chain until you find a DockableWindow, which in this case would be lbl.Parent.Parent.PointToScreen, though you may want to code that to check for null accordingly. I only experienced a problem when the pane wasn't docked, since there would be the extra space from the tab; using the DockableWindow took that into account.
That didn't work, either. The results were approximately the same as just using lbl.Parent:
private void link_MouseHover( object sender, EventArgs e ) { var lbl = (UltraFormattedLinkLabel) sender; var ui = lbl.UIElement.GetDescendant( typeof( FormattedLinkEmbeddableUIElement ) ) as FormattedLinkEmbeddableUIElement; if( ui == null || ui.IsDataFullyVisible ) return; var tt = new ToolTip( lbl ) { DisplayStyle = ToolTipDisplayStyle.BalloonTip, ToolTipText = lbl.Value.ToString( ) }; var window = ParentFrame( lbl ); if( window == null ) return; var loc = window.PointToScreen( this.Location ); tt.Show( new Point( loc.X, loc.Y + lbl.Height ) ); } private static DockableWindow ParentFrame( Control label ) { var parent = label.Parent; do { var window = parent as DockableWindow; if( window != null ) return window; parent = parent.Parent; } while( parent != null ); return null; }
The code that you posted isn't working because you're passing in "this.Location" to PointToScreen when it should be "lbl.Location".
Oops, yes I did. However, correcting that - and removing the adjustment for the label height - still didn't get it quite right (though it's at least back to being a stable location):
var loc = window.PointToScreen( lbl.Location ); tt.Show( loc );
With this, I would expect the tool tip point to be right above the "9" in "9/06/09 Network...".
The x-coordinate that you're passing in is where the label begins, so I would think that it's correct that it's shown to the left of the 9; if you want it to be positioned farther to the right, you would have to adjust the x position accordingly.
I also just noticed something with your code that I hadn't noticed initially: you're adding the height of the label to the y-coordinate of the location you're showing the ToolTip. Without doing this, my initial suggestion of lbl.Parent.PointToScreen(lbl.Location) works.
Thanks, that worked. For anyone who runs into this, here's the corrected code (at least for this circumstance):
private void link_MouseHover( object sender, EventArgs e ) { var lbl = (UltraFormattedLinkLabel) sender; var ui = lbl.UIElement.GetDescendant( typeof( FormattedLinkEmbeddableUIElement ) ) as FormattedLinkEmbeddableUIElement; if( ui == null || ui.IsDataFullyVisible ) return; var tt = new ToolTip( lbl ) { DisplayStyle = ToolTipDisplayStyle.BalloonTip, ToolTipText = lbl.Value.ToString( ) }; var loc = lbl.Parent.PointToScreen( lbl.Location ); tt.Show( new Point( loc.X, loc.Y ) ); }
Oh, misread that part. My test was also set too high if I used the DockableWindow (without adding the Height to the y-coordinate). If I used lbl.Parent.PointToScreen(lbl.Location) and used the result directly, the tooltip was displayed correctly:
var loc = lbl.Parent.PointToScreen(lbl.Location);tt.Show(new Point(loc.X, loc.Y));
The screen shot in my last response shows it without the label's height being added to the y-coordinate, and it's still too high. Adding the y-coordinate is what I did on the simple form I copied it from, so the tool tip notification popped up below the control.