WPF StackPanel с нажимает AND DoubleClick

Они оба объявляют целые числа на 32 бита, и как другие указанные плакаты, какой, который Вы используете, является главным образом вопросом синтаксического стиля. Однако они не всегда ведут себя тот же путь. Например, компилятор C# не позволит это:

public enum MyEnum : Int32
{
    member1 = 0
}

, но это позволит это:

public enum MyEnum : int
{
    member1 = 0
}

Пойди разберись.

7
задан Dave Clemmer 31 August 2011 в 15:43
поделиться

3 ответа

Лучший способ - настроить собственный обработчик кнопки мыши с тайм-аутом - если событие запускается снова в течение периода ожидания, то запускайте ваше сообщение 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);
4
ответ дан 6 December 2019 в 05:01
поделиться
 <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 приведет к событию (но не выполнит проверку if)

24
ответ дан 6 December 2019 в 05:01
поделиться

Другой вариант - добавить MouseBinding к InputBindings на StackElement, а затем добавить CommandBinding, активируемый MouseBinding. В целом это лучшая практика, чем механизмы, основанные на событиях, поскольку она позволяет избежать проблем с утечкой памяти, вызванных сильными ссылками. Он также обеспечивает отделение логики команды от представления.

При этом это не так просто, и привязка к событию дает отличный способ сокращения.

Само собой разумеется, сделайте фон вашей панели стека как минимум прозрачным, иначе он не будет обнаружен тестом нажатия мышью, когда вы нажимаете на «фон». Нулевые фоны пропускаются при обнаружении попаданий.

4
ответ дан 6 December 2019 в 05:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: