2017-10-16 1 views
0

Momentan erkenne ich Klicks in meinem Grid mit dem MouseLeftButtonUp Ereignis.C# wpf grid click event ohne zwei Callbacks

Ich öffne jedoch immer einen OpenFileDialog und wähle eine Datei aus. Das Mouse-Up-Ereignis geht durch das Dialogfeld und registriert ein Mouse-Up-Ereignis auf meinem Raster, wenn dies nicht der Fall ist.

Wie kann ich einen gültigen Mausklick (Maus und Maus nach oben) auf meinen Gittern erkennen, ohne mehrere Callbacks zu erstellen, um zu verfolgen, ob mein Element tatsächlich angeklickt wurde und nicht während des Mausklicks?

Beispiel:

System.Windows.Forms.OpenFileDialog o; 


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

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

} 

Wenn ich auf das Doppelte einer Datei im Dialog und mein Gitterfenster dahinter. Das mouse up-Ereignis wird aufgerufen.

+0

Haben Sie Codebeispiele, damit dieses Verhalten reproduziert werden kann? –

+0

@GingerNinja hinzugefügt ein Schnipsel – John

+0

was ist mit Ihrem XAML, Grid, etc. Es wäre schön zu sehen, ob das Problem reproduziert werden kann. –

Antwort

2

Es gibt keine einfache Möglichkeit, ein Click Ereignis ohne zwei Rückrufe auf einem Grid zu behandeln. Aber wir können etwas Hilfscode schreiben, um es zu erfüllen.

Dies ist, wie Sie meinen Helfer-Code verwenden können:

oben
<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# oben.

Dies ist mein Helfer Code:

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

Der Helfer-Code besteht aus zwei Klassen. Eine, die eine allgemeine Möglichkeit bietet, ein Ereignis an eine IInputElement anzuhängen, die andere, um eine grundlegende Click Implementierung bereitzustellen.

Sie können Ihre eigene andere Ereignisimplementierung selbst erstellen, indem Sie von RoutedEventExtension erben.