Двойной щелчок на флажке? - PullRequest
2 голосов
/ 04 февраля 2012

У меня есть несколько флажков, представляющих людей. Примерно так:

[ ] George
[ ] Sam
[ ] Steve
[ ] Lisa

Каждый может быть проверен индивидуально, и, конечно, также возможно проверить ни один вообще. Код запускается при изменении состояния проверки. Этот код использует состояние всех флажков в своем алгоритме.

Однако я бы хотел, чтобы они также вели себя как радиокнопки при двойном щелчке. То есть, если вы дважды щелкнете один, он должен стать отмеченным (независимо от его предыдущего состояния), а все остальные станут не отмеченными.

К сожалению, для флажка нет события двойного щелчка. Ясно, что мне нужно смоделировать двойной щелчок, используя mousedown (или мышь вверх) и комбинацию таймеров, секундомера и т. Д.

В конечном итоге я знаю, что найду решение путем экспериментов, поэтому, если я найду хорошее решение, я опубликую его здесь. Но у меня есть ощущение, что другие раньше уже имитировали двойные клики, и если кто-то может опубликовать хороший фрагмент для создания такого события из события mousedown, это было бы здорово.

P.S. Фрагмент должен как-то включать SystmInformation.DoubleClickTime. (Это количество миллисекунд, которое отличает двойной щелчок от «двух одиночных щелчков». Оно может отличаться от одного компьютера к другому.) Код для одного щелчка не должен выполняться, пока не истечет так много времени, чтобы гарантировать, что двойной щелчок не не в ожидании. (Поскольку, как я уже говорил, код использует состояние всех флажков.)

P.P.S. Я использую VB.NET Express 2008 для приложения winforms, но, возможно, я могу перевести форму C #, если понадобится, и думаю, что это, вероятно, применимо ко всем платформам .NET.

Ответы [ 3 ]

2 голосов
/ 04 февраля 2012
Вы можете использовать MouseDoubleClick, но событие не отображается через интерфейс Design. Чтобы использовать его, добавьте следующую строку в конструктор или событие загрузки вашей формы: checkBox1.MouseDoubleClick + = new MouseEventHandler (checkBox1_MouseDoubleClick); Это предполагает метод checkBox1.MouseDoubleClick, как показано ниже: void checkBox1_MouseDoubleClick (отправитель объекта, MouseEventArgs e) { бросить новый NotImplementedException (); }


Хорошо, последний пример не работает, вы правы; Событие DoubleClick никогда не возникает. Таким образом, это может быть немного "хакерским", но будет работать:

Расширьте класс CheckBox, создав, например, класс CheckboxExtended. В этом классе мы переопределяем метод WndProc и перехватываем сообщения двойного щелчка в окнах. Пример кода следующий:

public class CheckBoxExtended : CheckBox
{
    private const int WM_LBUTTONDBLCLK = 0x203;

    protected override void WndProc(ref Message m)
    {
        // Threat the message first
        if (m.Msg == WM_LBUTTONDBLCLK)
        {
            var lparam = m.LParam.ToInt32();
            var x = lparam & 0x0000FFFF;
            var y = (int) ((lparam & 0xFFFF0000) >> 16);

            OnMouseDoubleClick(new MouseEventArgs(MouseButtons.Left, 2, x, y, 0));
        }

        base.WndProc(ref m);
    }
}

Я все еще не уверен в разборе LParam для определения положения мыши. Просто дай мне пару секунд.

Чтобы использовать класс, просто сделайте, как я сказал ранее:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        checkBoxExtended1.MouseDoubleClick += new MouseEventHandler(checkBoxExtended1_MouseDoubleClick);
    }

    void checkBoxExtended1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
        MessageBox.Show(@"Test");
    }

}

Конечно, я принимаю форму с CheckBoxExtended на ней.

РЕДАКТИРОВАТЬ: Черт, я только что обнаружил, что я использовал двоичный файл или вместо двоичного и и. Теперь источник исправлен и должен возвращать правильные координаты.

РЕДАКТИРОВАТЬ 2: Хорошо, я создал класс в VB, но я не проверял его - мои навыки в VB также не так велики. Один совет: вы можете самостоятельно написать другое событие DoubleClick для расширенного класса и добавить необходимые украшения (атрибуты), чтобы конструктор мог их показать.

Public Class CheckboxExtended
    Inherits CheckBox

    Private Const WM_LBUTTONDBLCLK As Integer = &H203

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

        'Threat the message first
        If m.Msg = WM_LBUTTONDBLCLK Then

            Dim lparam = m.LParam.ToInt32()
            Dim x = lparam And &HFFFF
            Dim y = ((lparam And &HFFFF0000) >> 16)

            OnMouseDoubleClick(New MouseEventArgs(MouseButtons.Left, 2, x, y, 0))
        End If

        MyBase.WndProc(m)
    End Sub
End Class
2 голосов
/ 05 февраля 2012

Требуется операция, класс CheckBox был написан так, чтобы предполагать, что стандартное и двойное нажатие выключено Этот код сработал, вам придется отказаться от события MouseUp:

Imports System.ComponentModel

Public Class MyCheckBox
    Inherits CheckBox

    Public Sub New()
        Me.SetStyle(ControlStyles.StandardClick Or ControlStyles.StandardDoubleClick, True)
    End Sub

    Protected Overrides Sub OnMouseUp(ByVal mevent As System.Windows.Forms.MouseEventArgs)
        '' NOTE: do *not* call the base method
        MyBase.ResetFlagsandPaint()
    End Sub

    <EditorBrowsable(EditorBrowsableState.Always), Browsable(True)> _
    Public Shadows Custom Event DoubleClick As EventHandler
        AddHandler(ByVal value As EventHandler)
            AddHandler MyBase.DoubleClick, value
        End AddHandler
        RemoveHandler(ByVal value As EventHandler)
            RemoveHandler MyBase.DoubleClick, value
        End RemoveHandler
        RaiseEvent(ByVal sender As Object, ByVal value As EventArgs)
            Throw New InvalidOperationException  '' should never be raised by user code
        End RaiseEvent
    End Event
End Class

Обработчик события может выглядеть так:

Private Sub MyCheckBox_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles MyCheckBox1.DoubleClick, MyCheckBox2.DoubleClick, MyCheckBox3.DoubleClick, MyCheckBox4.DoubleClick

    For Each box As CheckBox In GroupBox1.Controls
        box.Checked = box.Equals(sender)
    Next
End Sub

Могут быть некоторые побочные эффекты операции, я не видел их, но не проверял их полностью. Я рекомендую вам сделать , а не на самом деле сделать это, функция в значительной степени не обнаруживается. Ни один пользователь никогда не поймет, что двойной щелчок теперь делает что-то особенное.

2 голосов
/ 04 февраля 2012

флажки имеют событие DoubleClick.

Класс CheckBox

DoubleClick Инфраструктура. Происходит, когда пользователь дважды щелкает CheckBox управление.

Редактировать

Как уже упоминалось в комментариях, по умолчанию используется то, что событие не вызывается.

Что вы можете сделать, так это создать собственный класс, унаследованный от CheckBox.
Вам нужно будет установить стиль StandardDoubleClick . Использование метода SetStyle () .
Затем переопределите метод OnDoubleClick , чтобы перехватить его до возникновения события.

public class MyCheckBox : CheckBox {

 MyCheckBox()
 {
    this.SetStyle(ControlStyles.StandardDoubleClick);
 }


 protected override void OnDoubleClick(EventArgs e)
 {
   Base.OnDoubleClick(e);
   //Do what ever you want... Like actually calling the DoubleClick event....
 }

}
...