2017-10-16 8 views
0

今、MouseLeftButtonUpイベントを使用して、グリッドのクリックを検出しています。2つのコールバックなしのC#wpfグリッドクリックイベント

しかし、OpenFileDialogを開いてファイルを選択するときはいつでも。マウスアップイベントはダイアログボックスを通過し、グリッド上にマウスアップイベントを登録します。

私の要素が実際にクリックされ、その上にマウスが上がっていないかどうかを追跡するために、複数のコールバックを作成することなく、有効なマウスクリック(マウスダウンとマウスアップ)を検出できますか?

例:

System.Windows.Forms.OpenFileDialog o; 


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

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

} 

私はダイアログで、ファイルをダブルクリックして、私のグリッドウィンドウはその背後にあります。マウスアップイベントが呼び出されます。

+0

この動作を再現できるようにコード例がありますか? –

+0

@GingerNinjaはスニペットを追加しました – John

+0

あなたのXAML、グリッドなどはどうでしょうか?問題を再現できるかどうかを確認することは良いことです。 –

答えて

2

Gridで2回のコールバックなしでClickイベントを処理する簡単な方法はありません。しかし、それを実現するヘルパーコードを書くことができます。上記

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

ヘルパーコードは2クラスで構成されています。いずれかのイベントをIInputElementにアタッチする一般的な方法を提供するもの、もう1つは基本的なClickのインプリメンテーションを提供するものです。

RoutedEventExtensionから継承して、自分で他のイベント実装を記述することができます。

関連する問題