How do I resize button backgroundImage in c#?
I could only find properties which gets button backgroundImage size.
Nothing sets size.
I use WinForms
BackgroundImageLayout would help...If Not then,
1)Take a Panel (panel1).
2)Bind you Button Event to panel(panel1)
3)Add another panel (panel2) to Panel1 in above with background image that you want to set and BackgroundImageLayout property as ImageLayout.Stretch
4)Then Resize the panel2
this would resize your image
Hope this helps
I will not get any simpler than that in WinForms:
private void yourbutton_Paint(object sender, PaintEventArgs e)
{
// base.OnPaint(e); optional
Rectangle rc = yourButton.ClientRectangle;
Rectangle ri = new Rectangle(Point.Empty, yourButton.BackgroundImage.Size);
// e.Graphics.FillRectangle(SystemBrushes.Control, rc); optional
e.Graphics.DrawImage(yourButton.BackgroundImage, rc, ri, GraphicsUnit.Pixel);
e.Graphics.DrawString(yourButton.Text, yourButton.Font,
SystemBrushes.ControlText, Point.Empty); // if needed
}
If you look at the code you'll see that it effectively really is just one line, or two if you have text on the button..
Related
Using a standard Label I aligned my image to the right side.
However there is a small indent (marked in red) that I cannot remove.
So my question: Is there an easy way to correctly align/snap an image to the right edge of a label? Or do I need to edit the label paint method so I can manually draw the image?
The label in question sits inside a "Panel", the following is my code:
label1.BackColor = System.Drawing.Color.Red;
label1.Image = global::TestProject.Properties.Resources.Header;
label1.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
label1.Size = new System.Drawing.Size(200, 40);
The simple answer appears to be: No there is no easy way to correctly align the image.
The "PictureBox" seems like the preferred component for working with images, however the image can be correctly aligned by editing the paint method of the label:
label1.Paint += new System.Windows.Forms.PaintEventHandler(this.label1_Paint);
And the paint method:
private void label1_Paint(object sender, PaintEventArgs e)
{
Image image = global::TestProject.Properties.Resources.Header;
Graphics g = e.Graphics;
//Align to far right: label width - image width
g.DrawImage(image, this.label1.Width - image.Width, 0);
}
Latest
//combination of pictureBox1.Invalidate(); and pictureBox1.Update();
pictureBox1.Refresh();
After pictureBox1.Refresh(); , it will trigger pictureBox1_Paint
Following code will have the icon remain on the picture box.
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (checkBox1.Checked)
{
e.Graphics.DrawIcon(IconCamera, rect);
}
}
Following code NOT! it will draw the icon and clear it soon after it was drawn in Paint (that why have my old question)
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics graphic = Graphics.FromHwnd(pictureBox1.Handle);
if (checkBox1.Checked)
{
graphic.DrawIcon(IconCamera, rect);
}
}
I thought these two graphics are same but it seem like they are not same.
May I know what is the difference of Graphics of PaintEventArgs of
pictureBox1 and Graphics from handle of pictureBox1?
Why DrawIcon on pictureBox1 Paint event with Graphics from handle of
pictureBox1 will disappear in Paint event but not in the function I
declared? thanks
Old Question
When I checked the checkbox then I will draw icon on the picture box,
Graphics graphic = Graphics.FromHwnd(pictureBox1.Handle);
if (checkBox1.CheckState.ToString() == "Checked")
{
Icon IconCamera = new Icon("cam.ico");
Rectangle rect = new Rectangle(100, 100, 32, 32);
graphic.DrawIcon(IconCamera, rect);
}
BUT After the picture box refresh,
pictureBox1.Refresh();
the drawn icon will disappear.
May I know what picturebox event OR else can I make use to put in the drawing icon code to maintain or always auto redraw the icon even after the picture box refresh()? thanks. I tried Paint and Validating of picturebox1 cannot work.
The best is to use two calls one after each other:
pictureBox1.Invalidate();
pictureBox1.Update();
This will force the picturebox to be redrawn.
Then I subscribe for Paint event, which is signalled when previous two lines of code are called (in case of redrawing the picturebox). Here I do the all the drawings.
In your case it would be something like this:
public void Paint(PaintEventArgs e)
{
if (checkBox1.Checked)
{
Rectangle rect = new Rectangle(100, 100, 32, 32);
Icon IconCamera = new Icon("cam.ico");
e.Graphics.DrawIcon(IconCamera, rect);
}
}
Then, subscribe for event CheckedChanged of checkBox1, and call there that two redrawing commands from the begin of this post.
It causes, that when user change the checked state of checkBox1, pictureBox1 will be forced to be redrawn and the icon will be drawn according to checkBox1 state.
You can avoid using a Graphics object and find another way. I don't know if you are forced in using an icon, but you can try to use a Label this way.
label1.Image = "yourImage.bmp" // you can use a bitmap
There here come your statement.
if(checkBox1.Checked) {
label1.Visible = true;
label1.Location = new Point(x, y); // your coordinate
}
Then you can handle checkBox1_CheckedChanged and code:
Void checkBox1_CheckedChanged(object sender, EventArgs e) {
if(!checkBox1.Checked) {
label1.Visible = false;
}
}
Hope this could help.
I have searching and the result cannot solve my case.
Actually I have a panel and I want the panel have thicker border than Windows given.
I need BorderStyle
BorderStyle.FixedSingle
thicker..
Thanks before
You have to customize your own Panel with a little custom painting:
//Paint event handler for your Panel
private void panel1_Paint(object sender, PaintEventArgs e){
if(panel1.BorderStyle == BorderStyle.FixedSingle){
int thickness = 3;//it's up to you
int halfThickness = thickness/2;
using(Pen p = new Pen(Color.Black,thickness)){
e.Graphics.DrawRectangle(p, new Rectangle(halfThickness,
halfThickness,
panel1.ClientSize.Width-thickness,
panel1.ClientSize.Height-thickness));
}
}
}
Here is the screen shot of panel with thickness of 30:
NOTE: The Size of Rectangle is calculated at the middle of the drawing line, suppose you draw line with thickness of 4, there will be an offset of 2 outside and 2 inside.
I didn't test the case given by Mr Hans, to fix it simply handle the event SizeChanged for your panel1 like this:
private void panel1_SizeChanged(object sender, EventArgs e){
panel1.Invalidate();
}
You can also setting ResizeRedraw = true using Reflection without having to handle the SizeChanged event as above like this:
typeof(Control).GetProperty("ResizeRedraw", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(panel1, true, null);
You may see a little flicker when resizing, just add this code to enable doubleBuffered for your panel1:
typeof(Panel).GetProperty("DoubleBuffered",
BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(panel1,true,null);
To create a panel with border I place a panel in a panel. The "border panel" has the background color of the wanted border color and a padding, while the padding size is the wanted border thickness.
The advantage of this solution is that there is no flickering and no problems with resize.
This can be very simple be created in the designer or in code behind.
Code behind:
Panel panel_Border = new Panel();
Panel panel_Embedded = new Panel();
panel_Border.BackColor = Color.Green;
panel_Border.Controls.Add(panel_Embedded);
// this is the border thickness
panel_Border.Padding = new System.Windows.Forms.Padding(6);
panel_Border.Size = new System.Drawing.Size(200, 100);
panel_Embedded.BackColor = System.Drawing.SystemColors.Control;
panel_Embedded.Dock = System.Windows.Forms.DockStyle.Fill;
Create a new, slightly larger panel and set the background colour to Black (or whatever). Place the original panel INSIDE the larger panel.
I was nicely supplied a code from Alex M, for painting the background image to a panel but realized that if a PictureBox's BackgroundImage has its Center image property set, the drawn image becomes stretched but not centered. I so far have this code:
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(pictureBox1.BackgroundImage,
new Rectangle(pictureBox1.Location, pictureBox1.Size));
}
This draws the background image to the panel but if pictureBox1's background image property is set to CENTER, it does not paint the image in the Center of the Rectangle, but instead stretches the image to fit the rectangle.
The only possible solution I've found is here but I can't make any sense of it.
The reason the image is being stretched is because the second parameter to DrawImage specifies the location and size of where you're drawing the image, and you're specifying the entire area of the picture box, not the area of the image itself.
If you want to center it, try something like this:
private void panel1_Paint(object sender, PaintEventArgs e)
{
var hPadding = (pictureBox1.Width - pictureBox1.BackgroundImage.Width) / 2;
var vPadding = (pictureBox1.Height - pictureBox1.BackgroundImage.Height) / 2;
var imgRect = new Rectangle(pictureBox1.Left + hPadding, pictureBox1.Top + vPadding, pictureBox1.BackgroundImage.Width, pictureBox1.BackgroundImage.Height);
e.Graphics.DrawImage(pictureBox1.BackgroundImage, imgRect);
}
I have a picturebox with a png in it. Yet even when I set the BackColor to Transparent, it is not transparent. Any ideas what might be wrong? :)
Thanks!
I have also faced the problem regarding transparent pictures.
you have to Draw it through code.
See my question A PictureBox Problem
EDIT:
In paint event (Control containing Background Image)
write this
//If added your image in project's resources get from there OR your Image location
Image img = yourNamespace.Properties.Resources.yourPicture;
e.Graphics.DrawImage(img,50,50,100,100);
Your PNG file should also have the transparent background. This is can be done while creating the image(png) files.
You really have to draw it through code. Place a pictureBox on your form, set sizeMode and docking as you like. Then you may fire the following function on the pictureBox's PAINT event:
public void LogoDrawTransparent(PaintEventArgs e)
{
// Create a Bitmap object from an image file.
Image myImg;
Bitmap myBitmap;
try
{
myImg = cls_convertImagesByte.GetImageFromByte(newImg);
myBitmap = new Bitmap(myImg); // #"C:\Temp\imgSwacaa.jpg");
// Get the color of a background pixel.
Color backColor = myBitmap.GetPixel(0, 0); // GetPixel(1, 1);
Color backColorGray = Color.Gray;
Color backColorGrayLight = Color.LightGray;
Color backColorWhiteSmoke = Color.WhiteSmoke;
Color backColorWhite = Color.White;
Color backColorWheat = Color.Wheat;
// Make backColor transparent for myBitmap.
myBitmap.MakeTransparent(backColor);
// OPTIONALLY, you may make any other "suspicious" back color transparent (usually gray, light gray or whitesmoke)
myBitmap.MakeTransparent(backColorGray);
myBitmap.MakeTransparent(backColorGrayLight);
myBitmap.MakeTransparent(backColorWhiteSmoke);
// Draw myBitmap to the screen.
e.Graphics.DrawImage(myBitmap, 0, 0, pictureBox1.Width, pictureBox1.Height); //myBitmap.Width, myBitmap.Height);
}
catch
{
try { pictureBox1.Image = cls_convertImagesByte.GetImageFromByte(newImg); }
catch { } //must do something
}
}
This is my class that is referenced in the above function:
class cls_convertImagesByte
{
public static Image GetImageFromByte(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
public static byte[] GetByteArrayFromImage(System.Drawing.Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
return ms.ToArray();
}
}
Thanks. chagbert.
From what I learned I can't do it within a windows form, as it doesn't have layers for the images. So guess will have to make it as WPF. :)
How did you create the background? Is that set by setting the Form.BackgroundImage?
If that background (the paper like image) is a container control, the transparency should just work.
However, If you are placing two PictureBox objects on top of eachother this doesn't work. The transparent area takes on the color of its parent object. If you have two PictureBox objects they both will have the Form as their parent. If this is your situation, it can be solved by setting the transparent image's Parent property to be the background image.
private void Form1_Load(object sender, EventArgs e)
{
transparentPictureBox.Parent = backgroundPictureBox;
}
When changing the Parent property, the Location of the tranparentPictureBox will become relative to its new parent. You'd have to subtract the x and y coordinates of the background image from the transparent image. See my answer on A PictureBox Question for an example with a screen shot.
AFAIK, you can not set the Parent in the Designer, only in code. Therefore, the Designer will still not show a transparent image, but at runtime it should.
The same problem occurs if you place a transparent Label on top of a PictureBox object.