Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF popup follow mouse

Tags:

c#

wpf

popup

That is my popup:

<Popup Name="Tedavi_Popup" IsOpen="False" Placement="MousePoint" >
        <Border BorderBrush="Gray" BorderThickness="1" >
            <TextBlock Background="WhiteSmoke" Padding="9,4,9,4" TextWrapping="Wrap" Name="popup"/>
        </Border>
    </Popup>

I have main grid and everything's in that grid.

That is my MouseMove event handler:

this.Tedavi_Popup.ClearValue(Popup.IsOpenProperty);
this.Tedavi_Popup.IsOpen = true;

I want keep the popups open all the time in the grid and have Popup follow the mouse.

Currently, the popup does not appear when the mouse moves. When the mouse stops, the popup appears on the bottom of the mouse. Everything works while the mouse is stopped. But mouse moving it doesn't appear.

How can I make it appear when the mouse is moving?


1 Answers

Since the MouseMove event fires rapidly while the mouse is moving, the popup isn't redrawing on the screen before the next move happens. This is why it doesn't appear to be showing while the mouse is moving.

To achieve the effect you're wanting, you'll want to explicitly place the popup instead of using the MousePoint placement.

Here's how you can do this:

  • Give a name to the main container of your window/control. In my below example, I'm using the Window, which I've named myWindow. You could choose to use your Grid, as long as it fills the surface area you want to have the mouse movement captured.

    • This allows you to target it in the next step.
  • Change the popup's set Placement to PlacementMode.Relative, set PlacementTarget to be the main container, and set HorizontalOffset and VerticalOffset to 0.

    • This will set the popup's placement to the top left corner of the main container, which we will then change in the event handler.
  • Set the MouseMove event handler on your main control, and in that handler, get the mouse's current position relative to the main control and use that to set the HorizontalOffset and VerticalOffset values:

    • This is what actually keeps the popup aligned with the mouse cursor without having to redraw it.

So you end up with XAML looking like this:

<Window x:Class="WpfApp2.MainWindow" MouseMove="popup_MouseMove" Name="myWindow">
    <Grid>
        <Popup Name="Tedavi_Popup" IsOpen="False" Placement="Relative" HorizontalOffset="0" VerticalOffset="0" PlacementTarget="{Binding ElementName=myWindow}">
            <Border BorderBrush="Gray" BorderThickness="1" >
                <TextBlock Background="WhiteSmoke" Padding="9,4,9,4" TextWrapping="Wrap" Name="popup" />
            </Border>
        </Popup>

    </Grid>
</Window>

And you're code looks like this:

private void popup_MouseMove(object sender, MouseEventArgs e)
{
    if (!this.Tedavi_Popup.IsOpen)
        this.Tedavi_Popup.IsOpen = true;

    var mousePosition = e.GetPosition(this.myWindow);
    this.Tedavi_Popup.HorizontalOffset = mousePosition.X;
    this.Tedavi_Popup.VerticalOffset = mousePosition.Y;

}
like image 79
John M. Wright Avatar answered Sep 13 '25 07:09

John M. Wright