没有两个回调的C#wpf网格点击事件

时间:2017-10-16 20:07:39

标签: c# wpf button grid

现在我正在使用MouseLeftButtonUp事件检测网格中的点击次数。

但是,每当我打开OpenFileDialog并选择一个文件时。鼠标注册事件将通过对话框并在我的网格上注册鼠标注册事件。

如何在我的网格上检测到有效的鼠标点击(鼠标按下并向上鼠标移动),而无需创建多个回调来跟踪我的元素是否实际被点击并且没有碰到鼠标在它上面?

示例:

System.Windows.Forms.OpenFileDialog o;


o = new System.Windows.Forms.OpenFileDialog();

if (o.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{

}

当我双击对话框中的文件时,我的网格窗口就在后面。调用鼠标注册事件。

1 个答案:

答案 0 :(得分:2)

如果Click没有两个回调,就没有简单的方法来处理Grid事件。但我们可以编写一些帮助代码来实现它。

这是您使用我的帮助程序代码的方法:

<Grid Background="Transparent">
    <local:RoutedEventExtension.Event>
        <local:ClickEvent Click="Grid_Click"></local:ClickEvent>
    </local:RoutedEventExtension.Event>
</Grid>

上面的XAML。

private void Grid_Click(object sender, EventArgs e)
{
    // Write your event handler code here.
}

C#以上。

这是我的帮助代码:

public abstract class RoutedEventExtension
{
    public static readonly DependencyProperty EventProperty = DependencyProperty.RegisterAttached(
        "Event", typeof(RoutedEventExtension), typeof(RoutedEventExtension),
        new PropertyMetadata(null, OnEventChanged));

    public static void SetEvent(DependencyObject element, RoutedEventExtension value)
    {
        element.SetValue(EventProperty, value);
    }

    public static RoutedEventExtension GetEvent(DependencyObject element)
    {
        return (RoutedEventExtension) element.GetValue(EventProperty);
    }

    private static void OnEventChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (!(d is IInputElement element))
        {
            throw new InvalidOperationException("RoutedEventExtension can only be attached on an IInputElement.");
        }

        var oldValue = (RoutedEventExtension) e.OldValue;
        var newValue = (RoutedEventExtension) e.NewValue;

        oldValue?.Detach();
        newValue.Attach(element);
    }

    protected IInputElement Target { get; private set; }

    private void Attach(IInputElement target)
    {
        Target = target;
        OnAttached();
    }

    private void Detach()
    {
        try
        {
            OnDetaching();
        }
        finally
        {
            Target = null;
        }
    }

    protected abstract void OnAttached();

    protected abstract void OnDetaching();
}

public sealed class ClickEvent : RoutedEventExtension
{
    public event EventHandler Click;

    protected override void OnAttached()
    {
        Target.MouseLeftButtonDown += OnMouseLeftButtonDown;
        Target.MouseLeftButtonUp += OnMouseLeftButtonUp;
        Target.LostMouseCapture += OnLostMouseCapture;
    }

    protected override void OnDetaching()
    {
        Target.MouseLeftButtonDown -= OnMouseLeftButtonDown;
        Target.MouseLeftButtonUp -= OnMouseLeftButtonUp;
        Target.LostMouseCapture -= OnLostMouseCapture;
    }

    private bool _isMouseDown;

    private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        _isMouseDown = true;
        Mouse.Capture(Target);
    }

    private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (!_isMouseDown)
        {
            return;
        }

        Mouse.Capture(null);
        OnClick();
    }

    private void OnLostMouseCapture(object sender, MouseEventArgs e)
    {
        _isMouseDown = false;
    }

    private void OnClick()
    {
        Click?.Invoke(this, EventArgs.Empty);
    }
}

帮助程序代码由两个类组成。一个用于提供在IInputElement上附加任何事件的常用方法,另一个用于提供基本Click实施。

您可以通过继承RoutedEventExtension

来自行编写自己的其他事件实现