使用带有透明颜色区域的图像按钮
Use image Button with transparent color area
我有一张 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;
而我在点击透明区域时,仍然算作点击Button。
如何让这个按钮只在点击彩色区域时调用点击事件?
当我点击透明区域时,我希望它算作点击这个按钮后面的对象。
您有两个选择:
使用 Button
和 Region
。
使用 Button
和 BackgroundImage
并检查用户点击的每个 Click
选项一仅可行如果你可以创建一个Region
,它需要一个GraphicsPath
,这意味着你需要创建shape 你需要来自 Graphics
primitves 像直线和曲线等..
如果您只有 Bitmap
和透明度,最好不要使用带有 Region
的 Button
。
相反,您可以使用 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
事件更容易,因为它已经有了鼠标位置..
如果您 need/want 改用 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..
如果您想检查所有鼠标单击事件并将它们中的每一个传递给父级,您将必须对它们全部进行编码。
- MouseDown event.
- Click event.
- MouseClick
- MouseUp event.
所以我们需要从 MouseDown
开始。我们可以在辅助函数 hitTest
中进行测试,因此我们可以重新使用它..:[=41=]
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
一次,然后在 Click
事件中传递简单、未修改的 e
参数:
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
编写所有四个事件的代码..
我有一张 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;
而我在点击透明区域时,仍然算作点击Button。
如何让这个按钮只在点击彩色区域时调用点击事件?
当我点击透明区域时,我希望它算作点击这个按钮后面的对象。
您有两个选择:
使用
Button
和Region
。使用
Button
和BackgroundImage
并检查用户点击的每个Click
选项一仅可行如果你可以创建一个Region
,它需要一个GraphicsPath
,这意味着你需要创建shape 你需要来自 Graphics
primitves 像直线和曲线等..
如果您只有 Bitmap
和透明度,最好不要使用带有 Region
的 Button
。
相反,您可以使用 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
事件更容易,因为它已经有了鼠标位置..
如果您 need/want 改用 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..
如果您想检查所有鼠标单击事件并将它们中的每一个传递给父级,您将必须对它们全部进行编码。
- MouseDown event.
- Click event.
- MouseClick
- MouseUp event.
所以我们需要从 MouseDown
开始。我们可以在辅助函数 hitTest
中进行测试,因此我们可以重新使用它..:[=41=]
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
一次,然后在 Click
事件中传递简单、未修改的 e
参数:
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
编写所有四个事件的代码..