I'm trying to add some background images to a few buttons in my Win Forms application. The three images are different sizes (ie pixel dimensions don't match, one is 128x128 and another is 256x256). I need the buttons to be identical in size (otherwise the GUI is horribly asymmetrical). Without changing the actual image files, how can I get the images to scale with button size?
I've tried creating my own class, and adding an event handler for the button resize event, but that doesn't seem to work. My code:
class CustomButton : Button {
internal void CustomButton_Resize( object sender, EventArgs e ) {
if ( this.BackgroundImage == null ) {
return;
}
var pic = new Bitmap( this.BackgroundImage, this.Width, this.Height );
this.BackgroundImage = pic;
}
}
and in the form:
this.buttonOne.Resize += new System.EventHandler(this.buttonOne.CustomButton_Resize);
Forgot to mention, the above code does not resize the images at all. The buttons still need to have different sizes to display the images completely.
Easiest way to add a background image to a .NET Button object and scale it to fit
I used this method to avoid any additional coding of new classes and event handlers. This helped me also avoid converting all Button objects into Image objects.
Add image to your Resources.resx file.
Click on your chosen button.
Navigate to the BackgroundImage property and choose the image you imported into the project's resources.resx file.
Navigate to the BackgroundImageLayout property and choose Stretch.
Make sure you don't have anything entered for the Image and Text properties or else they will interfere with your new background image.
The easy programmatic way
Say I have a button btn1, Following code is working perfectly in visual-studio-2010.
private void btn1_Click(object sender, EventArgs e)
{
btn1.Width = 120;
btn1.Height = 100;
}
void btn1_Resize(object sender, EventArgs e)
{
if ( this.BackgroundImage == null )
return;
var bm = new Bitmap(btn1.BackgroundImage, new Size(btn1.Width, btn1.Height));
btn1.BackgroundImage = bm;
}
The better way
You can add eventHandler in the constructor of your custombutton (just to ensure that you are adding eventhandler correctly)
class CustomButton : Button
{
CustomButton()
{
this.Resize += new System.EventHandler(buttonOne.CustomButton_Resize);
}
void CustomButton_Resize( object sender, EventArgs e )
{
if ( this.BackgroundImage == null )
return;
var pic = new Bitmap( this.BackgroundImage, new Size(this.Width, this.Height) );
this.BackgroundImage = pic;
}
}
Now when you will resize the button anywhere your image will get fit(scaled) to its new size.
You could start with something like this...
public class ImageButton : Control
{
public Image backgroundImage;
public Image BackgroundImage
{
get
{
return backgroundImage;
}
set
{
backgroundImage = value;
Refresh();
}
}
public ImageButton()
{
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.Clear(BackColor);
if(BackgroundImage != null)
e.Graphics.DrawImage(BackgroundImage, 0, 0, Width, Height);
base.OnPaint(e);
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
//base.OnPaintBackground(pevent);
}
}
You can just handle paint and draw the image yourself. You may also try using a PictureBox or some other control which has more scaling options
Related
I have created a winform and a picturebox, you can draw / place icons on the on the picturebox.
g2.DrawIcon(SystemIcons.Warning, new Rectangle(screenPositionX, screenPositionY, _levelWidth, _levelHeight));
like this
But my problem is I want to be able to remove the warning icons with the press of a button, but I dont know how.
I already tried g2.Clear, but this removes all the icons.
I also tried just drawing over them, but this draws over everything and I can't find the correct background color.
My question is, how do I remove a single drawn object?
You need a field that keeps track if the icons are to be drawn or not. Flip the value as a result of button presses, and when it comes time to draw (paint event) use the value to determine what to draw.
public partial class Form1 : Form
{
bool showIcons = true;
public Form1()
{
InitializeComponent();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
var wt = pictureBox1.ClientSize.Width;
var ht = pictureBox1.ClientSize.Height;
// draw grid
for (int i = 0; i < wt; i+=32)
{
e.Graphics.DrawLine(Pens.Black, i, 0, i, ht);
}
for (int j = 0; j < ht; j+=32)
{
e.Graphics.DrawLine(Pens.Black, 0, j, wt, j);
}
if (showIcons)
{
// draw icons
e.Graphics.DrawIcon(SystemIcons.Warning, 5*32-1, 2*32-1);
}
}
private void drawButton_Click(object sender, EventArgs e)
{
showIcons = true;
pictureBox1.Refresh();
}
private void clearButton_Click(object sender, EventArgs e)
{
showIcons = false;
pictureBox1.Refresh();
}
}
After you have painted something on a paper, you can't really take it back without either painting it over completely with the correct color, or discarding (clearing) everything and repainting only those objects that should remain. The same goes for a PictureBox.
If this icon is the only one that can be visible sometimes, and not visible other times, you could introduce a bool field in your form class. If that bool is true, you draw the icon, otherwise you don't. Then, when the user clicks the button, you can change the value of that field, and refresh the form.
Since you are showing very little code, I don't know any names of classes or methods in your solution, so consider this pseudo code!
// Pseudo code
class MyForm : Form
{
// The field that decides whether to draw the icon
private bool showWarningIcon = true;
// The button click handler
public void OnButtonClick()
{
showWarningIcon = false;
Invalidate();
}
// The paint handler
public override void OnPaint(PaintEventArgs e)
{
// Draw other things, then:
if (showWarningIcon)
{
g2.DrawIcon(SystemIcons.Warning, new Rectangle(screenPositionX, screenPositionY, _levelWidth, _levelHeight));
}
}
}
How can I freeze the video displayed in the CameraControl when TakeSnapshot() has been called in order to display the fetched image?
Basically, I would like to rebuild the same capture behaviour as in the devexpress TakePictureDialog class in my own form, because in the TakePictureDialog it does not seem to be possible to store the user-selected camera device, which I need to do in my app, though.
I followed the instructions and examples in these articles:
https://www.devexpress.com/Support/Center/Question/Details/T269133/obtaining-the-last-selected-camera-device-and-restoring-it-in-a-takepicturedialog
https://documentation.devexpress.com/WindowsForms/114582/Controls-and-Libraries/Editors-and-Simple-Controls/Camera-Control
UserAppDataReigistry not persisting
Welcome to the stackoverflow.
CameraControl doesn't provide that functionality itself.
Either way you can use the Paint event to render the image, obtained via TakeSnapshot.
Something like this:
private void CameraControl1_Paint(object sender, PaintEventArgs e)
{
CameraControl c = sender as CameraControl;
if (isStopped && img != null)
e.Graphics.DrawImage(img, new Rectangle(0,0, c.Width, c.Height));
}
bool isStopped = false;
Bitmap img;
private void button1_Click(object sender, EventArgs e)
{
img = cameraControl1.TakeSnapshot();
cameraControl1.Stop();
isStopped = true;
}
Credits from devexpress.com
I'm creating a windows application. In that application I need to show images on MenuStrip control items instead of text. Background image is working fine but the image got disappeared on hover and click.
Image on menu item
Disappeared on click/hover
Can some one have any idea, what to do to show a different image or same image on hover or click.
You have set the BackgroundImage property in the designer, which disappears on mouse hover.
Should set the Image property instead.
To show a different image on hover, register handlers for both MouseEnter and MouseLeave events, and change the Image property from the handlers.
private void toolStripMenuItem1_MouseEnter(object sender, EventArgs e)
{
this.toolStripMenuItem1.Image = global::WindowsFormsApp1.Properties.Resources.Hover;
}
private void toolStripMenuItem1_MouseLeave(object sender, EventArgs e)
{
this.toolStripMenuItem1.Image = global::WindowsFormsApp1.Properties.Resources.Normal;
}
Edit: For your requirement to show a different BackgroundImage when hover, use a custom render (first remove the MouseEnter/MouseLeave code above, and set both Image/BackgroundImage to none in designer).
public Form1()
{
InitializeComponent();
menuStrip1.Renderer = new BackgroundImageRenderer(); //menuStrip1 is the container for the toolstrip menu items.
}
private class BackgroundImageRenderer : ToolStripProfessionalRenderer
{
protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
{
if (e.Item.Name == "toolStripMenuItem1")
{
Image backgroundImage = global::WindowsFormsApp1.Properties.Resources.Normal;
if (e.Item.Selected)
backgroundImage = global::WindowsFormsApp1.Properties.Resources.Hover;
e.Graphics.DrawImage(backgroundImage, 0, 0, e.Item.Width, e.Item.Height);
}
else
{
base.OnRenderMenuItemBackground(e);
}
}
}
I get a pictureboxe and try to add it an action to change background Image upon click event happen, but there is no action. So, this is the code:
pieces bishopBB = new pieces();
public Form1()
{
// object of picturebox
bishopBB.Location = new Point(300, 455);
bishopBB.Parent = this;
bishopBB.Click += new System.EventHandler(pictureboxes_Click)
InitializeComponent();
}
private void pictureboxes_Click(object sender, EventArges e)
{
backgroundImage = Properties.Resources.black;
}
Looking at the name and other indicators I would assume (and hope) that pictureboxes_Click is a common click handler for many PictureBoxes.
So to access the one that has been clicked you need to cast sender to PictureBox and then set the BackgroundImage:
private void pictureboxes_Click(object sender, EventArges e)
{
((PictureBox)sender).BackgroundImage = Properties.Resources.black;
}
I'm a little amazed though that your spelling of backgroundImage compiles. The correct spelling BackgroundImage refers to the current class, usually the Form and it should also show, unless your Form has a black background already..
To change the current image of the PictureBox control, you need to refer to the control and reference the BackgroundImage property (not 'backgroundImage'):
private void pictureboxes_Click(object sender, EventArges e)
{
this.pictureboxes.BackgroundImage = Properties.Resources.black;
}
To change the background image of the form:
private void pictureboxes_Click(object sender, EventArgs e)
{
this.BackgroundImage = Properties.Resources.black;
}
To do this you can use the on_click property of the picturebox. You can then use the like picbox.image = whatever the image location is
I'm trying to create a button in my .NET 4.0 Winforms app in Visual Studio 2010 that is ONLY an image. I have a window that is borderless and has a background image that makes up my custom skin for this application. For the close/minimize buttons in the top right of the window, I wanted to create 2 simple buttons that are images only that look like the typical Windows close/minimize buttons.
I may be going about this design wrong, so if I am please let me know. So far I've determined that I need to create a subclass for Button that only renders the image. The final implementation needs to render different images for each button state (normal, hover, clicked, etc). Here is what I have so far:
public class ImageButton : Button
{
Pen pen = new Pen( Color.Red, 1.0f );
public ImageButton()
{
SetClientSizeCore( BackgroundImage.Width, BackgroundImage.Height );
}
protected override void OnPaint( PaintEventArgs e )
{
e.Graphics.DrawImage( BackgroundImage, 0, 0 );
//e.Graphics.DrawRectangle( pen, ClientRectangle );
//Rectangle bounds = new Rectangle( 0, 0, Width, Height );
//ButtonRenderer.DrawButton( e.Graphics, bounds, PushButtonState.Normal );
//base.OnPaint(pevent);
}
protected override void OnPaintBackground( PaintEventArgs e )
{
// Do nothing
}
}
At this point, assuming this design is appropriate, I need to know how to call SetClientSizeCore() appropriately. Calling it in the constructor raises an exception. I assume this is because the control hasn't had a chance to initialize yet. I'm not sure what function to override that will allow me to change the size of my button to fit the image after it has been initialized by .NET. Any ideas on this?
In the constructor, BackgroundImage is null.
You need to set the size when BackgroundImage is changed by overriding the property.
You should also shadow the Size property and add [DesignerSerializationVisibilty(DesignerSerializationVisibility.Hidden)] to prevent the size from being saved by the designer.
Wait until the BackgroundImage property is assigned so you'll know what size you need. Override the property like this:
public override Image BackgroundImage {
get { return base.BackgroundImage; }
set {
base.BackgroundImage = value;
if (value != null) this.Size = value.Size;
}
}
If you want to use ImageButtons, I'd recommend using BunifuUI as it has ImageButtons.
If you don't want to use BunifuUI, you can use a PictureBox as it also has a click event. Example:
private void pictureBox1_Click(object Sender, EventArgs e) {
webBrowser1.Navigate("https://www.google.com");
}