Вызвать нажатием кнопки компактная основа in.NET
Скажем, у меня есть панель со множеством кнопок и элементов управления PictureBox. С каждым элементом управления связано событие Click. Это сенсорное приложение, поэтому пользователь может быть немного неточным с их щелчком (или калибровка сенсорного экрана может быть не идеальной). Итак, я хотел бы обработать событие click на панели, а затем программно вызвать событие 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?
}
}
}
}
3 ответа:
Во-первых, попробуйте создать подкласс button и вызвать событие click из вашего собственного PerformClick. Кроме того, вы можете написать метод, который берет кнопку и выполняет щелчок. Сначала получите дескриптор элемента управления, затем p / вызовите функции API windows, чтобы отправить ему событие mousedown, а затем mouseup. Я считаю, что это функция SendMessage. Все, что вам нужно сделать, это написать логику, чтобы найти ближайшую кнопку и передать ее функции. Или запишите его как метод расширения для Кнопка
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; } } }
Поскольку вы не можете использовать
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 }
Поместите все материалы из вашего обработчика нажатия кнопки в отдельную функцию и вызовите эту функцию вместо запуска нажатия кнопки.
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 }