Wpf mouse events out of bounds user control problems

I have a strange problem, I have no idea how to fix it.

I am creating a color picker from scratch. I do this by creating a set of custom controls and combining them into a "master control".

When the user drags a tint selector, for example, I move the mouse down, move, and up (inside the custom tint control).

A simple bool dictates what happens, how much actual movement happens.

//Mouse down
 _isDrag = true;

//Mouse Move
if(!_isDrag) return; 
//Moving the position indicator shape thingy
//Calculating the hue

//Mouse Up
_isDrag = false;

      

But, if the mouse is outside the bounds of the shade selection, the mouse up event does not fire. Thus, when the user returns to the shade selection area, the shape indicator guides the shaft.

I'm sure some answer lies, but I'm afraid my search skills are not up to the task. I have no idea what to look for.

Thank you for your time.

Decision:

private bool _isDrag;

    //Request Mouse capture for the Container
    private void MsDown(object sender, MouseButtonEventArgs e)
    {
        _isDrag = true;
        Mouse.Capture(MainContainer);
    }

    //Release Mouse capture
    private void MsUp(object sender, MouseButtonEventArgs e)
    {
        _isDrag = false;
        Mouse.Capture(null);
    }

    //Move the handle vertically along the main container, with respect to it width - so it centered.
    private void MsMove(object sender, MouseEventArgs e)
    {
        if (!_isDrag) return;
        Canvas.SetTop(Handle, e.GetPosition(ContentRow).Y - Handle.ActualHeight / 2);
    }

      

Thanks for your reply!

Edit 2:

Follow my problem. While Capture mostly did the trick, I noticed that if you drag quickly outside of the user control, sometimes the handle would get stuck near the edge. If I moved the mouse slowly, this would not have happened. Weird. Also, I could never reach 0 and .ActualHeight

So I'll post my fix here in case another dude runs into this issue.

I split the grid like this:

<Grid.ColumnDefinitions>
        <ColumnDefinition Width="7"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
        <ColumnDefinition Width="7"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="7"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="7"></RowDefinition>
    </Grid.RowDefinitions>

      

With 7 is half the size of my handle (circle).

The content area (the actual area you can interact with visually) is in the middle cell (in a separate grid with false positives visibility).

The subdivision of the entire main mesh is an invisible rectangle used for hit testing.

And to move the handle

        private void MoveHandle()
    {
        _pos.X = _pos.X - Handle.ActualWidth/2;
        _pos.Y = _pos.Y - Handle.ActualHeight / 2;
         //this is just to be sure. I'm paranoid. Being a color picker, these actually matter a lot.
        _pos.X = Math.Max(Math.Min(_pos.X, RectColor.ActualWidth - Handle.ActualWidth/2), -Handle.ActualWidth / 2);
        _pos.Y = Math.Max(Math.Min(_pos.Y, RectColor.ActualHeight -Handle.ActualWidth/2), -Handle.ActualHeight/2);

        Canvas.SetLeft(Handle, _pos.X);
        Canvas.SetTop(Handle, _pos.Y);
    }

      

I have no idea why the previous code almost worked for me. It is basically the same as before. But somehow it works a million times better. Good luck!

+3


source to share


1 answer


The search term you are looking for is Mouse Capture . Capture in MouseDown and you can receive mouse events even after the mouse is out of your control.



+4


source







All Articles