Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A tooltip or something similar move with cursor in WPF

Is it possible to move a Tooltip or something like that with cursor when mouse goes on a specific control?

I tried TextBlock, but Margin property not work.

    private TextBlock tooltip = new TextBlock();
    private void imgRoom_MouseEnter(object sender, MouseEventArgs e)
    {           
        Point position = e.GetPosition((IInputElement)sender);
        tooltip.Visibility = System.Windows.Visibility.Visible; 
        tooltip.Margin = new Thickness(position.X, position.Y, 0, 0);           
        tooltip.Width = 100;
        tooltip.Height = 100;
        tooltip.Background = new SolidColorBrush(Colors.Red);
    }

    private void imgRoom_MouseMove(object sender, MouseEventArgs e)
    {
        Point position = e.GetPosition((IInputElement)sender);
        tooltip.Margin = new Thickness(position.X, position.Y, 0, 0);
    }
like image 232
Jalal Avatar asked Sep 28 '11 10:09

Jalal


2 Answers

You can achieve the effect using a Popup and some simple properties upon it. From window code...

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
  <Grid>
    <Rectangle Name="rect" Margin="50,50,0,0" Width="100" Height="100" Fill="LightBlue" MouseMove="Rectangle_MouseMove" MouseLeave="Rectangle_MouseLeave" />

    <Popup Name="floatingTip" AllowsTransparency="True" Placement="Relative" PlacementTarget="{Binding ElementName=rect}">
      <TextBlock>Look At Me</TextBlock>
    </Popup>
  </Grid>

</Window>

And this is what the codebehind would look like.

...
private void Rectangle_MouseMove(object sender, MouseEventArgs e)
{
  if (!floatingTip.IsOpen) { floatingTip.IsOpen = true; }

  Point currentPos = e.GetPosition(rect);

  // The + 20 part is so your mouse pointer doesn't overlap.
  floatingTip.HorizontalOffset = currentPos.X + 20;
  floatingTip.VerticalOffset = currentPos.Y;
}

private void Rectangle_MouseLeave(object sender, MouseEventArgs e)
{
  floatingTip.IsOpen = false;
}
...

So from the XAML you can see that the popup placement is relative to the rectangle. When you go mousing over the rectangle, it becomes visible, and its position is updated as the mouse moves. Naturally this is a very basic solution, but with some minor tweaks, handling events like 'MouseEnter' and property adjustment you can come up with some really neat effects.

like image 197
A.R. Avatar answered Sep 23 '22 19:09

A.R.


I don't know if this is a best practice, or if it performs well, but you could use an Adorner.

I've created a proof of concept before, but haven't used it in a production scenario (yet). The adorner can be used to create something like this (tooltip), or a custom mouse cursor or drop target icons.

Make sure you set IsHitTestVisible = false if the adorner doesn't need to be hit tested and might appear directly under the mouse location.

UPDATE

Just fully read the description of adorners:

Common applications for adorners include:

  • Adding functional handles to a UIElement that enable a user to manipulate the element in some way (resize, rotate, reposition, etc.).
  • Provide visual feedback to indicate various states, or in response to various events.
  • Overlay visual decorations on a UIElement.
  • Visually mask or override part or all of a UIElement.
like image 36
John B Avatar answered Sep 19 '22 19:09

John B