I was trying to Load a pictureBox in run time. There is no run time error. But the PictureBox does not show up.
Later on I also added InitializeComponent(), but it did not help.
My Code:
private void button1_Click(object sender, EventArgs e)
{
PictureBox picLoadingNew = new PictureBox();
picLoadingNew.BackColor = System.Drawing.Color.Transparent;
picLoadingNew.Image = global::QuiDip.Properties.Resources.ajax_loader_Long;
picLoadingNew.Location = new System.Drawing.Point(790, 760);
picLoadingNew.Name = "picLoadingNew";
picLoadingNew.Size = new System.Drawing.Size(142, 22);
picLoadingNew.Dock = DockStyle.Fill;
//InitializeComponent();
this.Controls.Add(picLoadingNew);
picLoadingNew.Show();
picLoadingNew.Visible = true;
}
You wont need .Show or .Visible lines as this would be the default anyway, but you do certainly need the this.Controls.Add(picLoadingNew) - as long as the form is going to be the parent and not a Panel or anything else. If the PictureBox is sitting on top of another control like a panel, you actually need: panel.Controls.Add(picLoadingNew) - and not your current this.Controls.Add(picLoadingNew) line.
What I would try first as I can't see anything too wrong with your code is, change the default location of your picture box to:
picLoadingNew.Location = new System.Drawing.Point(5, 5);
And remove the .Dock line.
This might be setting the PictureBox off screen (depending on the form's size?) - you haven't provided this so guessing what could be wrong. If the PictureBox is off screen, the new coordinates will force it to be top-left - so you should definitely see it then. Once you know it's working, you can then move it into position and set anchors later once you've proved the code is actually working.
You might find setting .SizeMode = StretchImage might be useful incase you're image is too large and again is "off screen". StretchImage will force the image to resize to fit nicely inside your PictureBox with the current .Size dimensions that you provided.
Something like:
PictureBox picLoadingNew = new PictureBox();
picLoadingNew.BackColor = System.Drawing.Color.Transparent;
picLoadingNew.Image = global::QuiDip.Properties.Resources.ajax_loader_Long;
picLoadingNew.Location = new System.Drawing.Point(5, 5);
picLoadingNew.Size = new System.Drawing.Size(142, 50);
picLoadingNew.SizeMode = PictureBoxSizeMode.StretchImage;
parent.Controls.Add(picLoadingNew);
The code above worked for me (using my own image of course!).
Hope that helps.
Your code should work but there is a little problem. If your image is exactly positioned at the same location of another image and its size is identical, you can't see it. It is located behind the current image on screen.
Remove the Show and Visible call but add a call to BringToFront
this.Controls.Add(picLoadingNew);
// picLoadingNew.Show();
// picLoadingNew.Visible = true;
picLoadingNew.BringToFront();
By the way, what is the point in giving a specific size to your new image if then you ask it to Fill the available space on its container?
Related
Currently I have zero code to show and display because I am new to using Visual Studio, Let me first explain what result I am trying to get so that you can better understand what I am trying to do. I will be making my first attempt at coding a program in C# using a great deal of images.
I added about 1300 images to imageList1 and I am trying to get all of these images to display vertically with their own picturbox or in a listview on form load so sooner or later making it so these images can be dragged and dropped into another window which will output code. I need these images to load from the program itself and not a local directory. Not sure if imageList is the best way to go for this or not.
I have googled and found nothing on what I am trying to do. Right now all I need help with is getting the images in imagelist to even display. I have googled for 2 days and found nothing on what I am looking to do, may be due to keywords entered but I found nothing.
try something like this (not sure of positioning picture boxes though):
PictureBox pb = default(PictureBox);
int x = 0, y = 3000;
foreach (Image img in imglist1.Images)
{
pb = new System.Windows.Forms.PictureBox();
pb.Image = img;
pb.Width = 1450;
pb.Height = 1450;
//x += 1000;
y -= 1000;
pb.Location = new System.Drawing.Point(x,y);
//pb.Location.X = x;
//pb.Location.Y = y;
this.Controls.Add(pb);
}
i have a class that draws waveforms of audio. I'm drawing it in OnPaint function. Now i need to draw a line that shows where on the waveform we are at current moment. I can calculate the position but when i try to draw it i need to call Invalidate() and that forces form to redraw all that waveform chart data (a lot of points).
So is there a way to put some transparent element over this one and then call Invalidate() only on that element? i was trying with picture box but no sucess...
//main form
private void timer100ms_Tick(object sender, EventArgs e)
{
customWaveViewer1.currentPosition = (int)((stream.Position / (float)stream.Length) * customWaveViewer1.Width);
customWaveViewer1.overlayLabel.Invalidate(false);
}
//drawing function in my class
private void overlayLabelInvalidate(object sender, PaintEventArgs e)
{
Pen pen = new Pen(Color.FromArgb(255, 0, 0, 0));
e.Graphics.DrawLine(pen, currentPosition, 0, currentPosition, this.Height);
}
//constructor
public CustomWaveViewer()
{
InitializeComponent();
this.DoubleBuffered = true;
this.PenColor = Color.DodgerBlue;
this.PenWidth = 1;
overlayLabel = new PictureBox();
overlayLabel.Size = new System.Drawing.Size(this.Width, this.Height);
overlayLabel.Location = new Point(this.Left, this.Top);
overlayLabel.Visible = true;
overlayLabel.BackColor=Color.FromArgb(0,0,0,0);
overlayLabel.Paint += new System.Windows.Forms.PaintEventHandler(this.overlayLabelInvalidate);
Controls.Add(overlayLabel);
}
Actually what you are saying is not exactly true.
In the painteventargs there is a rectangle indicating the small portion of the window that needs to be repainted.
Also when you invalidate, you don't necessarily need to invalidate the whole form.
In your case you might want to invalidate only the old and new position of the marker that indicates where you are in the waveform.
So in your algorithm of your paint method, it is really up to you to make it efficient and only paint that part of the window that really needs repainting and to skip the part that does not need repainting.
It really can make a huge difference.
To make it even more look professional, set double buffering on.
No need to hastle with bitmaps of the whole image you have yourself, that is just what double buffering is all about, and forms can do it for you.
I copied following excerpt from https://msdn.microsoft.com/en-us/library/windows/desktop/dd145137(v=vs.85).aspx
BeginPaint fills a PAINTSTRUCT structure with information such as the dimensions of the portion of the window to be updated and a flag indicating whether the window background has been drawn. The application can use this information to optimize drawing. For example, it can use the dimensions of the update region, specified by the rcPaint member, to limit drawing to only those portions of the window that need updating. If an application has very simple output, it can ignore the update region and draw in the entire window, relying on the system to discard (clip) any unneeded output. Because the system clips drawing that extends outside the clipping region, only drawing that is in the update region is visible.
In this case there is no simple output and taking this into account is adviced.
I am not saying that creating a bitmap will not work. I am saying that optimizing your drawing logic will solve it just as well.
The information above still stands as windows forms is built on top of the old win32 api.
So i'm trying to make a nice rounded switch that when clicked it will slide either left or right to basically turn something on or off (it could be used for other things). I have a rectangle version working somewhat ok (i have a few tweaks in mind that I want to make for it) but the problem I'm running into is by using rounded rectangles. I made a few classes to help my self in this. I have one called RoundRectanglePath. Using the Create method I give it a Rectangle (or x,y,w,h) and a radius for the corners and it returns a closed GraphicsPath that I can then use Graphics.[Fill|Draw]Path with. I then have a RoundRectangle class which is a just a control that acts very similar to a Label. I found that if I override the OnPaintBackground and not send the event to the base, but instead paint a rectangle the same color as it's Parent.BackColor than I get the illusion that the control is really round. (as a related side note I allow transparent)
For my RoundMovableSwitch class I use 2 RoundRectanglePaths to split the Control in half. The left is a green Color and the right is Pink (thinking about it now I could have just used a horizontal LinearGradient brush...ooops oh well) I then draw the string On and Off on opposing sides. To that control I add a RoundRectangle. When the user clicks on either the RoundRectangle or the MoveableSwitch the Control then moves the RoundRectangle left or right 1 pixel at a time. The movement works great. The problem I am having is this. The outside Edge of the RoundRectangle is the correct Transparent color. The inside edge is the wrong color. See RoundMovingSwitch 1 and 2 in picture below. Once I get the code working correctly I'll go back and reorganize the code a bit more.
The code is hosted on GitHub: Here
"The problem I am having is this. The outside Edge of the RoundRectangle is the correct Transparent color. The inside edge is the wrong color."
Not sure I understand the problem...
Are you trying to get rid of the blue corners that are outside the rounded edges?
If so, then try this in RoundRectangle:
public RoundRectangle()
{
this.ResizeRedraw = true;
this.VisibleChanged += new EventHandler(RoundRectangle_VisibleChanged);
}
private bool RegionSet = false;
void RoundRectangle_VisibleChanged(object sender, EventArgs e)
{
if (this.Visible && !RegionSet)
{
RegionSet = true;
var r = new RectangleEx(this.ClientRectangle);
var path = RoundRectanglePath.Create(r.ToRectangle(), this.Radius, this.Corners);
this.Region = new Region(path);
}
}
*If the size of the control changes then you should reset the Region() property to the new size.
Edit: To make it reset the Region when the size changes:
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
var r = new RectangleEx(this.ClientRectangle);
var path = RoundRectanglePath.Create(r.ToRectangle(), this.Radius, this.Corners);
this.Region = new Region(path);
}
In my program I have a picture box, containing a bitmap.(300x300 35kB .PNG file)
If 2 variables(x/z coord) are changed, I draw a new circle every second to the new position accordingly - a timer runs in the background, invoking this method.
void DrawEllipse()
{
// Retrieve the image.
bChamber = new Bitmap(global::Project.Properties.Resources.driveChamber1);
gChamber = Graphics.FromImage(bChamber);
gChamber.FillEllipse(brushChamber, VirtualViewX(), VirtualViewY(), 10, 10);
pictureBoxDriveView.Image = bChamber;
}
Now I'm looking for ways to optimize the performance. Redrawing the pic every 0.2s e.g. slows the program so much, I cant do anything else.
But ultimately I need a more fluent movement of the circle, you can Imagine how it laggs with the 1000ms refresh rate.
Is there a better way to do this, then loading the whole bitmap every time?
Use the Controls the way they were intended.
do not redraw the Bitmap yourself.
just load it 1x in the Picturebox.
handle the Paint event of the picturebox to draw the ellipse
invalidate the Picturebox whenever your coords change.
Draw the circle ONE time in a control (PictureBox)
Put the control across the 300x300 picture box.
When, and only when, the variables change, update the location of the picturebox with the circle.
This way you prevent drawing too many times.
Try setting the DoubleBuffered property of the form to true. This generally results in improved performance.
Also, you should put this
// Retrieve the image.
bChamber = new Bitmap(global::Project.Properties.Resources.driveChamber1);
In the class constructor.
Try this, it does not load the image from disk every time, so it is less expensive.
private Image _origImage = new Bitmap(global::Project.Properties.Resources.driveChamber1);
void DrawEllipse()
{
// Retrieve the image.
Image bChamber = new Bitmap((Image)this._origImage.Clone());
Graphics gChamber = Graphics.FromImage(bChamber);
gChamber.FillEllipse(brushChamber, VirtualViewX(), VirtualViewY(), 10, 10);
pictureBoxDriveView.Image = bChamber;
}
I want to draw a rectangle on the screen. I guess the most appropriate way is use a form without boarder.
Form frm = new Form();
frm.StartPosition = FormStartPosition.Manual;
frm.Location = new Point(GlobalPosX, GlobalPosY);
frm.Size = new Size(101, 30);
frm.BackColor = System.Drawing.Color.Yellow;
frm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
frm.Show();
The created from is not as the given size. It's size is similar to the window having boarder. The displayed window is bit larger as I given and the position is also moved little bit upper and left.
Is there another way to achieve my goal?
Use the ClientSize property instead of Size:
frm.ClientSize = new Size(101,30);
If you want to draw rectangle on the screen, you can draw it directly: http://bytes.com/topic/c-sharp/answers/263740-draw-directly-screen
Drawing C# graphics without using Windows Forms
That like talks about making a border-less window. From there, just use the Graphics object to draw whatever you'd like