문제

내가 필요할 수 있 처리 더블 클릭한 번의 클릭 이벤트 WPF StackPanel.그러나 같은 것은 없으로 StackPanel 의 DoubleClick 이벤트입니다.내가 하고 싶은 2 가지 작업에서 이러한 2 하십시오.

어떤 아이디어는 어떻게 해야 할까요?

감사

도움이 되었습니까?

해결책

가장 좋은 방법은 자신의 오른쪽 마우스 버튼을 처리기와 시간 제한-이벤트 발생한 제한 시간 동안,다음 화재의 doubleclick 메시지,그렇지 않으면 전화를 클릭 한 번으로 처리기입니다.여기에 몇 가지 예제 코드(편집: 원래 발견 ):

/// <summary>
/// For double clicks
/// </summary>
public class MouseClickManager {
    private event MouseButtonEventHandler _click;
    private event MouseButtonEventHandler _doubleClick;

    public event MouseButtonEventHandler Click {
        add { _click += value; }
        remove { _click -= value; }
    }

    public event MouseButtonEventHandler DoubleClick {
        add { _doubleClick += value; }
        remove { _doubleClick -= value; }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="MouseClickManager"/> is clicked.
    /// </summary>
    /// <value><c>true</c> if clicked; otherwise, <c>false</c>.</value>
    private bool Clicked { get; set; }

    /// <summary>
    /// Gets or sets the timeout.
    /// </summary>
    /// <value>The timeout.</value>
    public int DoubleClickTimeout { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="MouseClickManager"/> class.
    /// </summary>
    /// <param name="control">The control.</param>
    public MouseClickManager(int doubleClickTimeout) {
        this.Clicked = false;
        this.DoubleClickTimeout = doubleClickTimeout;
    }

    /// <summary>
    /// Handles the click.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
    public void HandleClick(object sender, MouseButtonEventArgs e) {
        lock (this) {
            if (this.Clicked) {
                this.Clicked = false;
                OnDoubleClick(sender, e);
            }
            else {
                this.Clicked = true;
                ParameterizedThreadStart threadStart = new ParameterizedThreadStart(ResetThread);
                Thread thread = new Thread(threadStart);
                thread.Start(e);
            }
        }
    }

    /// <summary>
    /// Resets the thread.
    /// </summary>
    /// <param name="state">The state.</param>
    private void ResetThread(object state) {
        Thread.Sleep(this.DoubleClickTimeout);

        lock (this) {
            if (this.Clicked) {
                this.Clicked = false;
                OnClick(this, (MouseButtonEventArgs)state);
            }
        }
    }

    /// <summary>
    /// Called when [click].
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
    private void OnClick(object sender, MouseButtonEventArgs e) {
        if (_click != null) {
            if (sender is Control) {
                (sender as Control).Dispatcher.BeginInvoke(_click, sender, e);
            }
        }
    }

    /// <summary>
    /// Called when [double click].
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
    private void OnDoubleClick(object sender, MouseButtonEventArgs e) {
        if (_doubleClick != null) {
            _doubleClick(sender, e);
        }
    }
}

그런 다음,컨트롤 받고 싶 이벤트:

MouseClickManager fMouseManager = new MouseClickManager(200);
fMouseManager.Click += new MouseButtonEventHandler(YourControl_Click); 
fMouseManager.DoubleClick += new MouseButtonEventHandler(YourControl_DoubleClick);

다른 팁

 <StackPanel MouseDown="StackPanel_MouseDown">
   <!--stackpanel content-->
    <TextBlock>Hello</TextBlock>
</StackPanel>

그런 다음 이벤트에서 처리기:

 private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.ClickCount >= 2)
        { 
            string hello; //only hit here on double click  
        }
    }

작업해야 합니다.참고는 하나의 클릭하면서 StackPanel 을 칠 것 이벤트(하지만 실패하는 경우 체크인)

...합니다.@MoominTroll 의 솔루션이 완벽하게 허용됩니다.또 다른 옵션은 감싸 스택에서 패널 컨텐츠 제어를 지원하는 두 번 이벤트를 클릭합니다.

<ContentControl MouseDoubleClick="DoubleClickHandler" >
    <StackPanel>

    </StackPanel>
</ContentControl>

또 다른 옵션은 추가 MouseBinding 을 InputBindings 에 StackElement 를 추가 CommandBinding 는 의해 활성화된 MouseBinding.전체에서 이것은 더 나은 연습보다 이벤트 기반의 메커니즘을 피할 수 있기 때문에 메모리 누출로 인해 발생하는 문제 강한 참조가 있습니다.그것은 또한 제공을 위한 분리를 명령의 논리에서 표현입니다.

그는 말했다,그것의 똑바로 앞으로 첨부하기 이벤트는 훌륭한 바로 가기가 있습니다.

고 그것은 말할 것도 없고,당신의 stackpanel 배경에는 최소한 투명한 또는 손해를 입지 않도록 충분히 마우스로 클릭 hit 테스트를 클릭할 때"배경".Null 배경 건너뛰에 의해 충돌 감지합니다.

나는 비슷한 문제가 있었(응답을 클릭 한 번 이벤트 및 당 추가적인 작업의 경우 더블릭 이벤트).나는이 문제를 해결에 이 방법:

1)정의하고 선포하는 일부 정수를 개최하는 마지막 클릭 timestamp

int lastClickTimestamp;

2)Window_Loaded 초기화 방법 이전에 이 변수 선언으로 일부 숫자보다 큰 200

lastClickTimestamp = 1000;

3)추가로 마우스 단추 핸들러를 당신의 스택이 패널

stackPanel.MouseLeftButtonUp += new MouseButtonEventHandler(stackPanel_MouseLeftButtonUp);

4)다음과 같은 방법으로 추가

void stackPanel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (e.Timestamp - lastClickTimeStamp < 200)
        {
            //double click
        }
        lastClickTimeStamp = e.Timestamp;

        //single click
    }

이 코드는 쓸모 없는 필요하신 경우에는 별도로 감지 하나의 클릭 및 더블 클릭의 이벤트입니다.는 상황을 소개하고 좀 더 복잡,하지만 분명히 해결할 수 있습니다.

완전한 답변을 사용하여 WPF DispatcherTimer.우리가 만든 타이머에 수요와 그것을 분리 할 경우를 방지하기 위해 자원의 막힘.

C#:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

public partial class MainWindow : Window
{
    DispatcherTimer dt;

    bool clear_timer()
    {
        if (dt == null)
            return false;
        dt.Tick -= _single_click;
        dt = null;
        return true;
    }

    private void _click(Object sender, MouseButtonEventArgs e)
    {
        if (clear_timer())
            Debug.Print("double click");
        else
            dt = new DispatcherTimer(
                        TimeSpan.FromMilliseconds(GetDoubleClickTime()),
                        DispatcherPriority.Normal,
                        _single_click,
                        Dispatcher);
    }

    void _single_click(Object sender, EventArgs e)
    {
        clear_timer();
        Debug.Print("single click");
    }

    public MainWindow() { InitializeComponent(); }

    [DllImport("user32.dll")]
    static extern uint GetDoubleClickTime();
 };

XAML:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel Orientation="Horizontal"
                Background="AliceBlue"
                Width="100"
                Height="100"
                MouseLeftButtonDown="_click" />
</Window>

가 있는 간편한 솔루션을니다.

에 StackPanel 의 이벤트 PreviewMouseLeftDown(예를 들어),는지 확인할 수 있습 MouseButtonEventArgs.ClickCount 속성 값은 2 입니다.1=단 한 번의 클릭 2=더블 클릭

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top