0
  • I have a child that contains four buttons, double click each button it clears data in the main form/parent form
  • below I have my code which counts the button click and perform the event task upon count. Some how its not working at all.
public enum CommandType
    {
        SetCycleCount,
        ClearFaultCount,
        ClearGUIControl,
        ClearBackData
    }
 public partial class Child: Form
    {
        public delegate void OnDblClickedBtn(CommandType operationType, bool state);
        public event OnDblClickedBtn BtnClickedEvent;
   public CtrlTest()
        {
            InitializeComponent();
            SetCommand();
        }

   public void SetCommand()
        {
            SetCycleCnt_btn.Tag = CommandType.SetCycleCount;
            ClrFaultCnt_btn.Tag = CommandType.ClearFaultCount;
            ClrGuiCtrl_btn.Tag = CommandType.ClearGUIControl;
            ClrBackData_btn.Tag = CommandType.ClearBackData;

            var btnList = Controls.OfType<Button>().ToList();

            foreach (var btn in btnList)
            {
                btn.DoubleClick += CommandOnClicked;
            }
        }

   private void CommandOnClicked(object sender, EventArgs e)
        {
            var status = (Button)sender;
            BtnClickedEvent?.Invoke((CommandType)status.Tag, status.Enabled);
        }
  }
  1. Parent Form (message-box is just to check whether its working or not)
 child = new Child();
 child.BtnClickedEvent += BtnClickedEvent;
 child.MdiParent = this;
 child.Show();


public int btnCount = 0;
private void BtnClickedEvent(CommandType commandType, bool state)
        {
            switch (commandType)
            {
                case CommandType.ClearBackData:
                    if (btnCount==0)
                    {
                        //TODO
                        MessageBox.Show("Double clicked");
                        btnCount += 2;
                    }
                    else
                    {
                        MessageBox.Show("Double click to perform the action");
                        
                    }
                    break;
                   ....
            }
         }
EverActive
  • 15
  • 4
  • Can you describe `its not working at all.` ? – Chetan Jul 25 '22 at 02:28
  • It's the superlative form of `new string[] { "doesn't work", "really doesn't work", "doesn't work at all" }` – Stefan Wuebbe Jul 25 '22 at 02:39
  • @Chetan If I double click on the Button `ClrBackData_btn` then it should fire an event and the message box with the message `Double clicked` should show. Else, other than double click,(let's say single click) then the message box `Double click to perform the action` should show, but at the moment neither of those are showing up. – EverActive Jul 25 '22 at 02:54
  • 1
    The standard click events including the Buton.DoubleClick are [disabled](https://referencesource.microsoft.com/#system.windows.forms/winforms/managed/system/winforms/Button.cs,62) by design, it is not a _double click_ control. However, if you really need to make it one, then subclass and set `SetStyle(ControlStyles.StandardDoubleClick | ControlStyles.StandardClick, true);` in the constructor to enable the standard click events. Then, you will have the _Click_ and _DoubleClick_ events to handle them separately. Note, this also enables the right clicks on the button. – dr.null Jul 25 '22 at 03:59
  • See [How to: Distinguish Between Clicks and Double-Clicks.](https://learn.microsoft.com/en-us/dotnet/desktop/winforms/how-to-distinguish-between-clicks-and-double-clicks?view=netframeworkdesktop-4.8&redirectedfrom=MSDN) – dr.null Jul 25 '22 at 04:01
  • You need instance of a form to send a command. So the child form needs an instance of the parent form. See my two form project at following : https://stackoverflow.com/questions/34975508/reach-control-from-another-page-asp-net – jdweng Jul 25 '22 at 05:25
  • @jdweng I appreciate your guidance, thank you – EverActive Jul 26 '22 at 01:03

1 Answers1

1

One way to do this is by overriding WndProc in a ButtonWithDoubleClick : Button class:

class ButtonWithDoubleClick : Button
{
    const int WM_LBUTTONDBLCLK = 0x203;
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        switch (m.Msg)
        {
            case WM_LBUTTONDBLCLK:
                OnDoubleClick(EventArgs.Empty);
                break;
        }
    }
}

Replace the Button instances in MainForm.Designer.cs

// private System.Windows.Forms.Button buttonTryDoubleClick; 
private double_click.ButtonWithDoubleClick buttonTryDoubleClick;

private void InitializeComponent()
{
    // this.buttonTryDoubleClick = new System.Windows.Forms.Button();
    this.buttonTryDoubleClick = new double_click.ButtonWithDoubleClick();
    ...
}

Responding to one or two clicks

public MainForm()
{
    InitializeComponent();
    buttonTryDoubleClick.Click += ButtonTryDoubleClick_Click;
    buttonTryDoubleClick.DoubleClick += ButtonTryDoubleClick_DoubleClick;
}

private async void ButtonTryDoubleClick_Click(object sender, EventArgs e)
{
    _isDoubleClick = false;
    // Allow some time to get the second click if it's coming.
    await Task.Delay(100);
    if(!_isDoubleClick)
    {
        MessageBox.Show("Clicked");
    }
}

bool _isDoubleClick = false;
private void ButtonTryDoubleClick_DoubleClick(object sender, EventArgs e)
{
    _isDoubleClick = true;
    BeginInvoke((MethodInvoker)delegate 
    {
        MessageBox.Show("Double Clicked");
    }); 
}

Response for one and two clicks.

IVSoftware
  • 5,732
  • 2
  • 12
  • 23
  • Probably better to have the single/double-click detection baked into a [Self-contained ButtonWithDoubleClick](https://github.com/IVSoftware/button-with-double-click.git) class. – IVSoftware Jul 25 '22 at 13:52
  • 1
    Thank you so much for your detailed and elaborate explanation, its really nice of you. Have a good day – EverActive Jul 26 '22 at 01:05