简体   繁体   English

Wpf鼠标事件超出用户控件问题的范围

[英]Wpf Mouse Events outside the bounds of a user control issue

I have a weird issue I have no ideea how to fix. 我有一个奇怪的问题,我不知道如何解决。

I'm creating a color picker from scratch. 我正在从头开始创建一个颜色选择器。 I'm doing so by creating a set of user controls and putting them together in a "master control". 我是通过创建一组用户控件并将它们放在一个“主控件”中来实现的。

When a user drags over the hue picker, for example, I handle the mouse down, move and up (inside the hue picker user control). 例如,当用户拖动色调选择器时,我将鼠标向下移动,向上移动(在色调选择器用户控件内)。

A simple bool dictates what happens, as far as the actual moving goes. 一个简单的布尔决定了发生了什么,就实际移动而言。

//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 up occurs outside of the bounds of the hue picker, the mouse up event doesn't fire. 但是,如果鼠标向上发生在色调选择器的边界之外,则鼠标向上事件不会触发。 Thus, when the user returns to the area of the hue picker, the shape indicator thingy runs rampart. 因此,当用户返回到色调选择器的区域时,形状指示器就会运行。

I am certain an answer lies somewhere but I'm afraid my searching skills are not up to the task. 我确定答案就在某处,但我担心我的搜索能力无法胜任。 I've no idea what to look for. 我不知道该找什么。

Thank you for your time. 感谢您的时间。

Solution: 解:

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's width - so it's centered.
    private void MsMove(object sender, MouseEventArgs e)
    {
        if (!_isDrag) return;
        Canvas.SetTop(Handle, e.GetPosition(ContentRow).Y - Handle.ActualHeight / 2);
    }

Thank you for your answer! 谢谢您的回答!

Edit 2: 编辑2:

Following up on my issue. 跟进我的问题。 While Capture basically did the trick, I noticed that, if fast dragging outside the bounds of the user control , sometimes the handle would get stuck close to the edge. 虽然Capture基本上完成了这个技巧,但我注意到,如果快速拖动到用户控件的边界之外,有时手柄会卡在靠近边缘的位置。 If I would move the mouse slowly, this wouldn't happen. 如果我慢慢移动鼠标,就不会发生这种情况。 Weird. 奇怪的。 Also, I could never reach 0 and .ActualHeight 此外,我永远无法达到0和.ActualHeight

So I'll post my fix here, just in case another dude encounters this issue. 所以我会在这里发布我的修复,以防另一个家伙遇到这个问题。

I split my 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 being half the size of my handle (a circle). 7是我手柄的一半(圆圈)。

The content area (the actual area you can interact with visually) is in the middle cell (in a separate grid with false hit test visibility). 内容区域(您可以在视觉上与之交互的实际区域)位于中间单元格中(在具有错误命中测试可见性的单独网格中)。

Spanning the entire main grid 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 I had almost worked. 我不知道为什么以前的代码我几乎工作了。 It's basically the same thing as before. 它与以前基本相同。 But, somehow, this performs a million times better. 但是,不知何故,它的表现要好一百万倍。 Good luck! 祝好运!

The search term you are looking for is Mouse Capture . 您正在寻找的搜索词是Mouse Capture Capture in your MouseDown, and you can get mouse events even after the mouse leaves your control. 在MouseDown中捕获,即使鼠标离开您的控件也可以获得鼠标事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM