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

时间:2014-09-28 04:25:22

标签: c# wpf events mouse

我有一个奇怪的问题,我不知道如何解决。

我从头开始创建颜色选择器。我是通过创建一组用户控件并将它们放在一个"主控件中来实现的。

例如,当用户拖动色调选择器时,我会向下移动鼠标,向上移动(在色调选择器用户控件内)。

就实际移动而言,一个简单的布尔决定了会发生什么。

//Mouse down
 _isDrag = true;

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

//Mouse Up
_isDrag = false;

但是,如果鼠标向上发生在色调选择器的边界之外,则鼠标向上事件不会触发。 因此,当用户返回到色调选择器的区域时,形状指示器就会运行。

我确定答案就在某处,但我担心我的搜索能力无法胜任。 我不知道该找什么。

感谢您的时间。

解决方案:

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);
    }

感谢您的回答!

编辑2:

跟进我的问题。虽然Capture基本上完成了这个技巧,但我注意到,如果快速拖动到用户控件的边界之外,有时手柄会卡在靠近边缘的位置。如果我慢慢移动鼠标,这不会发生。奇怪的。此外,我永远无法达到0和.ActualHeight

所以我会在这里发布我的解决方案,以防另一个家伙遇到这个问题。

我像这样拆分我的网格:

<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>

7是我手柄的一半(圆圈)。

内容区域(您可以通过视觉交互的实际区域)位于中间单元格中(在具有错误命中测试可见性的单独网格中)。

跨越整个主网格是一个用于命中测试的不可见矩形。

移动手柄

        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);
    }

我不知道为什么之前的代码几乎工作了。它与以前基本相同。但是,不知何故,它的表现要好一百万倍。祝你好运!

1 个答案:

答案 0 :(得分:4)

您要查找的搜索字词为Mouse Capture。在MouseDown中捕获,即使在鼠标离开后也可以获得鼠标事件。