2015-05-31 2 views
3

У меня есть изображение в PNG с прозрачным и нормальным цветом.Используйте кнопку изображения с прозрачной цветовой областью

Я использую это для одной кнопки:

this.Button1.BackColor = System.Drawing.Color.Transparent; 
this.Button1.BackgroundImage = Image; 
this.Button1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; 
this.Button1.FlatAppearance.BorderSize = 0; 
this.Button1.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent; 
this.Button1.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent; 
this.Button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 
this.Button1.Location = new System.Drawing.Point(0, 0); 
this.Button1.Margin = new System.Windows.Forms.Padding(0); 
this.Button1.Name = "Skin"; 
this.Button1.Size = new System.Drawing.Size(294, 194); 
this.Button1.TabIndex = 7; 
this.Button1.UseVisualStyleBackColor = false; 

И когда я нажимаю на прозрачной области, он по-прежнему считается одним нажатием на кнопку.

Как я могу сделать эту кнопку только щелчком мыши, когда я нажимаю на цветную область?

И когда я нажимаю на прозрачную область, я хочу, чтобы она считалась щелчком по объекту за этой кнопкой.

+0

Вы можете ограничить область кнопки, если вы можете получить в GraphicsPath, который исключает прозрачные области. К сожалению, вы не можете преобразовать растровое изображение в путь. – TaW

+0

Да, я ищу это в течение нескольких дней, но я не вижу решения для этого. Я действительно хочу создать пользовательскую кнопку в winform, но все, что мне нужно сделать, это сделать эту пользовательскую кнопку прямоугольником ... – Tranoze

+0

Итак, как выглядят ваши изображения? Простые формы могут быть выполнены, но сложные изображения не будут работать с точностью. См. Начало (только) этого [этого сообщения] (http://stackoverflow.com/questions/30134352/how-to-create-a-clickable-irregularly-shaped-region/30137794?s=1|0.0000#30137794) например, для ограничения привязки элемента управления к форме. – TaW

ответ

2

У вас есть два варианта:

  • Используйте 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

  1. MouseDown событие.
  2. Нажмите мероприятие.
  3. MouseClick
  4. 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 также ..

+0

Большое спасибо! Он работает, и я использую мышь для мыши, а не щелчок .. – Tranoze

+0

Но есть ли все равно, чтобы вызвать кнопку мыши на кнопке мыши/мышь вверх/мышь вниз (все события мыши) ?. Я хочу, чтобы все события мыши переходили к родительскому, а не только к щелчку мыши. – Tranoze

+0

Конечно, см. Мой обновленный ответ .. – TaW

Смежные вопросы