在.net紧凑框架中点击触发按钮

本文关键字:按钮 net 框架 | 更新日期: 2023-09-27 17:49:51

假设我有一个面板,有许多按钮和图片框控件。每个控件都有一个关联的Click事件。这是一个触摸屏应用程序,因此用户的点击可能有点不精确(或者触摸屏校准可能不完美)。所以,我想处理面板上的点击事件,然后以编程方式调用按钮或PictureBox的点击事件,如果点击接近按钮/图片。

许多其他答案建议使用"PerformClick"事件,但这在紧凑框架中不支持。替代品吗?我的代码:

private void pnlButtons_Click(object sender, EventArgs e)
{
    Point ptClick = Control.MousePosition;
    foreach (Control cntrl in pnlButtons.Controls)
    {
        // Make sure the control is visible!
        if (cntrl.Visible)
        {
            // Click close to control?
            if ((ptClick.X > (cntrl.Left - 5)) &&
                (ptClick.X < (cntrl.Right + 5)) &&
                (ptClick.Y > (cntrl.Top - 5)) &&
                (ptClick.Y < (cntrl.Bottom + 5)))
            {
                // Click Button or PictureBox without cntrl.PerformClick?
            }
        }
    }
}

在.net紧凑框架中点击触发按钮

由于您不能使用PerformClick,因此在这种情况下您将无法依赖控件的Click事件处理程序自动触发。相反,只需创建一个方法,它接受一个控件,并从该控件中找出要执行的操作。例子:

private void pnlButtons_Click(object sender, EventArgs e)
{
    Point ptClick = Control.MousePosition;
    foreach (Control cntrl in pnlButtons.Controls)
    {
        // Make sure the control is visible!
        if (cntrl.Visible)
        {
            // Click close to control?
            if ((ptClick.X > (cntrl.Left - 5)) &&
                (ptClick.X < (cntrl.Right + 5)) &&
                (ptClick.Y > (cntrl.Top - 5)) &&
                (ptClick.Y < (cntrl.Bottom + 5)))
            {
                handleClick (cntrl);
            }
        }
    }
}
private void handleClick(Control c)
{
    if (c == button1)
    {
        // handle button1 click, e.g. by calling its `Click` handler
    }
    else if (c == picureBox1)
    {
        // handle pictureBox1 click
    }
    // et cetera
}

首先,尝试子类化button并从您自己的PerformClick调用click事件。否则,你可以写一个方法,它接受一个按钮并执行一个点击。首先获取控件的句柄,然后调用windows API函数向其发送一个mousedown事件,然后发送mouseup事件。我想应该是SendMessage函数。然后您所要做的就是编写逻辑来找到最近的按钮并将其传递给函数。或者,将其作为Button

的扩展方法编写https://msdn.microsoft.com/en-us/library/windows/desktop/ms644950%28v=vs.85%29.aspx

编辑:下面是通过向控件发送mousedown和mouseup消息来模拟单击的完整代码:

// Windows constants for mouse messages
private const int WM_LBUTTONDOWN        = 0x0201;
private const int WM_LBUTTONUP          = 0x0202;
// P/Invoke for SendMessage
[DllImport("coredll.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, int nMsg, IntPtr wParam, IntPtr lParam);
// Method to click a control
public void ClickControl(IntPtr hWnd)
{
    // Send a MOUSE_DOWN and MOUSE_UP message to the control to simulate a click
    SendMessage(hWnd, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
    SendMessage(hWnd, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
}
// Method to handle click event on parent Panel control
private void pnlButtons_Click(object sender, EventArgs e)
{
    // See if the click point is close to a (visible) button and if so, click the button.
    // The user was probably a little imprecise or the screen might need re-calibration.
    Point pt = pnlButtons.PointToClient(Cursor.Position);
    // Now look for any Button / PictureBox controls nearby
    foreach (Control cntrl in pnlButtons.Controls)
    {
        Rectangle inflated = cntrl.Bounds;
        inflated.Inflate(4, 5);
        if (cntrl.Visible && inflated.Contains(pt))
        {
            // Simulate a click on the control
            ClickControl(cntrl.Handle);
            break;
        }
    }
}

将按钮单击处理程序中的所有内容放到一个单独的函数中,并调用该函数,而不是触发按钮单击。

private void pnlButtons_Click(object sender, EventArgs e)
{
    Point ptClick = Control.MousePosition;
    foreach (Control cntrl in pnlButtons.Controls)
    {
        // Make sure the control is visible!
        if (cntrl.Visible)
        {
            // Click close to control?
            if ((ptClick.X > (cntrl.Left - 5)) &&
                (ptClick.X < (cntrl.Right + 5)) &&
                (ptClick.Y > (cntrl.Top - 5)) &&
                (ptClick.Y < (cntrl.Bottom + 5)))
            {
                PerformActionsOnClick();
            }
        }
    }
}
private void MyButton_Click(object sender, EventArgs e)
{
    PerformActionsOnClick();
}
void PerformActionsOnClick()
{
    //do your stuff here
}