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
에서 상속하면 직접 다른 이벤트 구현을 작성할 수 있습니다.
이 동작을 재현 할 수 있도록 코드 예제가 있습니까? –
@GingerNinja가 코드 예 – John
을 추가하여 XAML, 눈금 등은 어떨까요? 문제를 재현 할 수 있는지 확인하는 것이 좋습니다. –