2017-10-16 1 views
0

지금은 MouseLeftButtonUp 이벤트를 사용하여 그리드의 클릭을 감지하고 있습니다.두 콜백없이 C# wpf grid 클릭 이벤트

그러나 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에서 두 번의 콜백없이 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); 
    } 
} 

도우미 코드는 두 개의 클래스로 구성

이 내 도우미 코드입니다. 하나는 일반적인 이벤트를 IInputElement에 부착하는 방법이고 다른 하나는 기본 Click 구현을 제공하는 것입니다.

RoutedEventExtension에서 상속하면 직접 다른 이벤트 구현을 작성할 수 있습니다.