上一篇笔记中我们通过重写OnRender 来绘制了一个圆角按钮,在这篇笔记中我们将处理鼠标操作以实现点击事件的响应。

Control 基类中有函数OnMouseEnter ,OnMouseLeave ,OnMouseLeftButtonDownOnMouseLeftButtonUp 等四个函数分别在鼠标进入空间、离开控件、鼠标在控件区域按下和抬起时会被调用。因此我们可以重写这四个函数以实现鼠标事件的响应。

代码直达:链接

protected override void OnMouseEnter(MouseEventArgs e)
{
    base.OnMouseEnter(e);
    Trace.WriteLine("Mouse Enter");
    Trace.Flush();
}

protected override void OnMouseLeave(MouseEventArgs e)
{
    base.OnMouseLeave(e);
    Trace.WriteLine("Mouse Leave");
    Trace.Flush();
}

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
    base.OnMouseLeftButtonDown(e);
    Trace.WriteLine("Mouse Left Button Down");
    Trace.Flush();
}

protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
    base.OnMouseLeftButtonUp(e);
    Trace.WriteLine("Mouse Left Button Up");
    Trace.Flush();
}

DJjQjMEzL-Fl14Kc3l8Z7VDN3AIpOCrP32rsO4fbdAA.gif

注册路由事件以实现和事件属性以在Xaml中可以配置事件响应函数

public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent(
        "Click",
        RoutingStrategy.Bubble,
        typeof(RoutedEventHandler),
        typeof(MyCustomRenderControl)
    );

public event RoutedEventHandler Click
{
    add => AddHandler(ClickEvent, value);
    remove => RemoveHandler(ClickEvent, value);
}

修改前文中鼠标事件响应函数以触发Click事件的处理程序。同时我们增加一个_clicking 标志以判断是否鼠标的按下和抬起均在控件内部,以确保仅接受只在控件内部按下并抬起的情况下才触发Click 事件。

protected override void OnMouseEnter(MouseEventArgs e)
{
    base.OnMouseEnter(e);
    Trace.WriteLine("Mouse Enter");
    Trace.Flush();

    _clicking = false;
}

protected override void OnMouseLeave(MouseEventArgs e)
{
    base.OnMouseLeave(e);
    Trace.WriteLine("Mouse Leave");
    Trace.Flush();

    _clicking = false;
}

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
    base.OnMouseLeftButtonDown(e);
    Trace.WriteLine("Mouse Left Button Down");
    Trace.Flush();

    _clicking = true;
}

protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
    base.OnMouseLeftButtonUp(e);
    Trace.WriteLine("Mouse Left Button Up");
    Trace.Flush();
    if (_clicking)
    {
        RaiseEvent(new RoutedEventArgs(ClickEvent));
        _clicking = false;
    }
}

LQ1lZ-3XeIxaP5lOhjZfo8ZcISpI4zfAnkIfa2QXYXQ.gif