2017-10-16 26 views
0

À l'heure actuelle, je détecte les clics dans ma grille en utilisant l'événement MouseLeftButtonUp.Événement de clic de grille C# wpf sans deux rappels

Cependant, chaque fois que j'ouvre un OpenFileDialog et que je sélectionne un fichier. L'événement de la souris passe par la boîte de dialogue et enregistre un événement de souris sur ma grille quand il ne devrait pas. Comment puis-je détecter un clic de souris valide (souris et souris) sur mes grilles sans avoir à créer plusieurs rappels pour suivre si mon élément a été cliqué et n'est pas passé à la souris quand il est dessus?

Exemple:

System.Windows.Forms.OpenFileDialog o; 


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

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

} 

Lorsque je double cliquez sur un fichier dans la boîte de dialogue et la fenêtre de ma grille est derrière elle. L'événement de souris vers le haut est appelé.

+0

avez-vous des exemples de code pour que ce comportement puisse être reproduit? –

+0

@GingerNinja a ajouté un extrait – John

+0

Qu'en est-il de votre XAML, grille, etc. Il serait bon de pouvoir voir si le problème peut être reproduit. –

Répondre

2

Il n'existe pas de moyen facile de gérer un événement Click sans deux rappels sur un Grid. Mais nous pouvons écrire du code d'aide pour le remplir.

Voici comment vous pouvez utiliser mon code d'assistance:

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

XAML ci-dessus.

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

C# ci-dessus.

Ceci est mon code d'assistance:

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

Le code d'aide se compose de deux classes. Un pour fournir un moyen commun d'attacher un événement sur un IInputElement, l'autre pour fournir une implémentation de base Click.

Vous pouvez écrire vous-même votre propre implémentation d'événement en héritant de RoutedEventExtension.