У вас есть два варианта:
Используйте Button
с Region
.
Используйте Button
с BackgroundImage
и проверить, что попадает пользователь с каждым Click
Вариант один только возможно , если вы можете создать Region
, который принимает GraphicsPath
, что означает, что вы необходимо создать форму вам нужно от Graphics
примитивов, таких как линии и кривые и т. д.
Если вы только имеют Bitmap
с прозрачностью, вам лучше не использовать Button
с Region
.
Вместо этого вы можете использовать свой Button1
и при каждом нажатии вы проверяете прозрачность щелкнутого пикселя.
Если прозрачна вы звоните событие щелчка управления под ним ..
private void Button1_MouseClick(object sender, MouseEventArgs e)
{
Size r = Button1.BackgroundImage.Size;
// check that we have hit the image and hit a non-transparent pixel
if ((e.X < r.Width && e.Y < r.Height) &&
((Bitmap)Button1.BackgroundImage).GetPixel(e.X, e.Y).A != 0)
{
Console.WriteLine("BUTTON clicked"); // test
// do or call your click actions here!
}
// else pass the click on..
else
{
// create a valid MouseEventArgs
MouseEventArgs ee = new MouseEventArgs(e.Button, e.Clicks,
e.X + Button1.Left, e.Y + Button1.Top, e.Delta);
// pass it on to the stuff below us
pictureBox1_MouseClick(pictureBox1, ee);
Console.WriteLine("BUTTON NOT clicked"); // test
}
}
Обратите внимание, что проверка предполагает, что у вас есть нормальный макет с изображения кнопки в верхнем левом углу и не масштабирования , Если вам нужно масштабировать изображение, вы должны сохранить масштабированное растровое изображение, чтобы выполнить проверки. Но если вы можете использовать немасштабированный образ, вы должны сделать это, так как это будет выглядеть лучше.
Обратите внимание, как создать правильный MouseEventArgs
параметр для управления ниже, так что вы можете получить доступ к кнопке или расположение мыши там, а ..
Также обратите внимание, что проще использовать MouseClick
событие вместо в Click
случае, как это имеет место мышей уже ..
Если вам необходимо/хотят использовать Click
событие вместо этого, вы можете пропустить создание EventArgs
, так как она не имеет содержательные данные; просто отпустите e
от клика ..
Вот как можно начать Click
события:
private void Button1_Click(object sender, EventArgs e)
{
// we need the location of the clicked pixel:
Point clickLocation = Button1.PointToClient(Control.MousePosition);
// the rest can proceed as above, just with simple EventArgs..
Если вы хотите проверки на все событие щелчка мыши и пройти каждый из них вниз к родителю вы должны закодировать их все.
Сначала давайте посмотрим на order of events on MSDN
- MouseDown событие.
- Нажмите мероприятие.
- MouseClick
- MouseUp event.
Таким образом, мы должны начать в MouseDown
. Мы можем сделать тест на вспомогательную функцию hitTest
, поэтому мы можем повторно использовать его ..:
Button clickedButton = null;
MouseEventArgs ee = null;
void hitTest(Button btn, MouseEventArgs e)
{
Size r = btn.BackgroundImage.Size;
// check that we have hit the image and hit a non-transparent pixel
if ((e.X < r.Width && e.Y < r.Height) &&
((Bitmap)btn.BackgroundImage).GetPixel(e.X, e.Y).A != 0)
{
clickedButton = btn;
ee = new MouseEventArgs(e.Button, e.Clicks, e.X + btn.Left, e.Y + btn.Top, e.Delta);
}
else clickedButton = null;
}
Теперь мы закодировать все четыре события. Нам нужно вызвать hitTest
только один раз, и мы проходим простой, неизмененный e
параметр в Click
событии:
private void Button1_MouseDown(object sender, MouseEventArgs e)
{
hitTest(sender as Button, e);
if (sender != clickedButton)
yourParent_MouseDown((sender as Button).Parent, ee);
else // do your stuff
}
private void Button1_Click(object sender, EventArgs e)
{
if (sender != clickedButton)
yourParent_Click((sender as Button).Parent, e);
else // do your stuff
}
private void Button1_MouseClick(object sender, MouseEventArgs e)
{
if (sender != clickedButton)
yourParent_MouseClick((sender as Button).Parent, ee);
else // do your stuff
}
private void Button1_MouseUp(object sender, MouseEventArgs e)
{
if (sender != clickedButton)
yourParent_MouseUp((sender as Button).Parent, ee);
else // do your stuff
}
Конечно, вы должны кодировать все четыре события для yourParent
также ..
Вы можете ограничить область кнопки, если вы можете получить в GraphicsPath, который исключает прозрачные области. К сожалению, вы не можете преобразовать растровое изображение в путь. – TaW
Да, я ищу это в течение нескольких дней, но я не вижу решения для этого. Я действительно хочу создать пользовательскую кнопку в winform, но все, что мне нужно сделать, это сделать эту пользовательскую кнопку прямоугольником ... – Tranoze
Итак, как выглядят ваши изображения? Простые формы могут быть выполнены, но сложные изображения не будут работать с точностью. См. Начало (только) этого [этого сообщения] (http://stackoverflow.com/questions/30134352/how-to-create-a-clickable-irregularly-shaped-region/30137794?s=1|0.0000#30137794) например, для ограничения привязки элемента управления к форме. – TaW