user8210624
user8210624

Reputation:

WPF popup follow mouse

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?

Upvotes: 4

Views: 6567

Answers (1)

John Wright
John Wright

Reputation: 4607

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;

}

Upvotes: 12

Related Questions