I have a Picture Box in a panel and I need to see it move from this panel to another one upon user click. To give you a better picture, I have a connect four game where I have a chip or whatever you call it moving with the mouse on top of the connect four grid and I need it to go in the grid and obviously stay in its place. This is the code I have right now. The chip seems to go down but never stay there
Graphics g = grid.CreateGraphics();
grid.Controls.Add(picBox);
for (int i = 0; i < newYloc; i++)
{
picBox.Location = new Point(newXloc, picBox.Top + 1);
// moves the chip by 1 down each iteration
picBox.Show();
}
if (playerNo == 1) g.DrawImage(red, newXloc, newYloc, 65, 65);
else g.DrawImage(gold, newXloc, newYloc, 65, 65);
where grid is the panel where I have the connect four grid, picBox is the Picture Box which before this piece of code resides in another panel.
Related
I am having a panel in Winforms which loads panels in it during a method call.
In the method call I have written following code:
//to get number of panel present in main panel so that new panel position can be set
int counT = panel1.Controls.Count;
Panel p = new Panel();
p.Location = new Point(3, 3 + (counT * 197));
p.Size = new Size(280, 150);
//To add panel to parent panel
panel1.Controls.Add(p);
Every time I call the method it will load a panel in the main panel. Everything works fine if i didn't scroll the scroll bar. Once I scroll the Scroll bar to down and after that i call the method, the distance between panels increases.
As per logic written the distance between two panel should be 197 pixel along Y axis, but it is increasing by more.
I have set AutoScroll=true
Any help !!!
That's quite strange behavior which I didn't know until now (and I have a lot experience in WF). It can be seen when the parent panel is scrolled when the code above is executed. I was thinking that child control positions are relative to the ClientRectangle, but it turns out that they are accounting the DisplayRectangle.
Shortly, instead of this
p.Location = new Point(3, 3 + (counT * 197));
use this
var parentRect = panel1.DisplayRectangle;
p.Location = new Point(parentRect.X + 3, parentRect.Y + 3 + (counT * 197));
Panel.AutoScrollPosition affects Location property of all child controls. Scrolling works in this way. So you should keep in mind that, for example you could store current scroll position, move position to (0,0), add new controls, and restore scroll position after all
//to get number of panel present in main panel so that new panel position can be set
int counT = panel1.Controls.Count;
var pos = this.panel1.AutoScrollPosition; // Whe are storing scroll position
this.panel1.AutoScrollPosition = new Point(Size.Empty);
Panel p = new Panel();
p.Location = new Point(3, 3 + (counT * 197));
p.Size = new Size(280, 150);
p.BorderStyle = BorderStyle.FixedSingle;
//To add panel to parent panel
panel1.Controls.Add(p);
this.panel1.AutoScrollPosition = new Point(Math.Abs(pos.X), Math.Abs(pos.Y)); // We are restoring scroll position
It's me again, with a weird problem. I created a code which reads xml file and uses g.Drawstring function to get my sorted xml text to pictureBox1. So I got advanced and made the pictureBox scrollable and noticed the problem. When the text in pictureBox was off screen (invisible), when I scrolled back to it, it wasn't there anymore. Same happens if I just take my application and drag it off screen, so that text disappears, the text gets deleted, but if I load my program again (browse the xml file again) it refreshes, but that doesn't help, becuase I need to make it so that the text is always there.
Here is a part of my code, I hope it helps:
private void DrawInPictureBox(int index)
{
pictureBox1.Refresh();
using (XmlReader reader = XmlReader.Create(openFileDialog1.FileNames.ElementAt(index)))
{
y = 0;
while (reader.Read())
{
if (reader.IsStartElement())
{
if (reader.Name == "Something")
{
string Dat = reader.GetAttribute("Dat");
Graphics g = pictureBox1.CreateGraphics();
if (reader.Read())
{
string m = reader.Value.Trim();
g.DrawString(m, new Font("Arial", 10), Brushes.Black, 0, y * 15 + 20);
g.DrawString(Dat + "ok", new Font("Arial", 10), Brushes.Black, 150, y * 15 + 20);
y = y + 1;
}}}}}}
The pictureBox has a panel underneath it, so it is scrollable, but even if there is no panel the text gets deleted when taken off screen.
Thank you!
Some points:
It would be best if you can subscribe to PictureBox.OnPaint event and use the e.Graphics to draw your XML elements
With regards to scroll, there is a possibility that the location of your scrollable control is moving in one direction only which makes it invisible from the screen.
Try to debug the location of the scroll position by writing the values of scroll-X and scroll-Y position in output window via Console.WriteLine() or System.Debug.WriteLine(), chances are there are negative values, or out of boundary values. (In your case the value of y in the g.DrawString())
My form1 size is 800,600
Then i have two panels in the form1 designer:
Panel1 is at location: 0,24 size: 200,437
Panel2 is at location: 584,24 size: 200,437
The result is two panels at each side of the form.
Now i did in my program when you put the mouse somewhere in the form1 area its showing a pictureBox i create in the form1 constructor:
pb = new AnimatedPictureBox.AnimatedPictureBoxs();
pb.Visible = false;
pb.Size = new Size(500, 350);
pb.Location = new Point((ClientSize.Width - pb.Width) / 2,
(ClientSize.Height - pb.Height) / 2);
The problem is that the new pictureBox variable pb is not in the size that will fill all the area between the two panels.
I want the size of the pictureBox to fill almost all the space between the two panels Width and Height maybe to leave some space like 5 spaces each side so there will be a border.
How can i calculate what the pictureBox size should be ?
EDIT**
This is an image where the program is working regular. On each panel on the left and right i added 4 pictureBoxes.
When i move my mouse cursor inside one of the pictureBoxes area its showing its content in a larger pictureBox in the middle.
And this is how it looks like when i put the mouse cursor in one of the pictureBoxes area the pictureBox in the middle is not big enough its Width and Height dosent make the big pictureBox to be excatly between the two panels. The big pictureBox not high and not wide enough.
if you want to make your layout stable even after resizing you should use Dock property for your panels and set Anchor for your picture box. Like that:
panel1.Dock = DockStyle.Left;
panel2.Dock = DockStyle.Right;
pb.Anchor = AnchorStyles.Left | AnchorStyles.Right;
And in general to place it in the center you can use something like that:
var width = this.Width - panel1.Width - panel1.Margin.Horizontal
- panel2.Width - panel2.Margin.Horizontal;
pb.Size = new Size(width, 300); // put your needed height here
pb.Top = this.Height/2 - pb.Height/ 2;
pb.Left = panel2.Left + panel2.Width + panel2.Margin.Right;
I want create manually PictureBox and Label on horizontal Panel, The count of PictureBox and Label on panel Unknown maybe 200 or more or less, I use the below code to do that but i face two troubles first one:
I want add the new object created in the first not in the end for example if i created items "A B C D E" want it add on Panel "E D C B A" want always the new come to first.
Note: Panel width "230" Height "710"
Second trouble:
Currently when i use Panel scroll bar to go down than add new objects find happen big free space between the last object created and the new and if i used scroll again to go down and created new object on panel happen more big free space.
int Right = 50, Top = 0;
// Create Image + Text
PictureBox pbox = new PictureBox();
pbox.Size = new Size(140, 80);
pbox.Location = new Point(Right, Top);
pbox.Image = Image.FromFile("");
Panel1.Controls.Add(pbox);
// Create label
Label lblPlateNOBAR = new System.Windows.Forms.Label();
lblPlateNOBAR.Text = lblPlateNO.Text;
lblPlateNOBAR.Location = new Point(Right + 20, Top + 80);
Panel1.Controls.Add(lblPlateNOBAR);
Top = Top + 150;
In order to make the objects insert into the panel, you'd need to move the controls which already exist in the panel:
int right = 50;
// Create Image + Text
PictureBox pbox = new PictureBox();
pbox.Size = new Size(140, 80);
pbox.Location = new Point(right, 0);
pbox.Image = Image.FromFile("");
// Create label
Label lblPlateNOBAR = new System.Windows.Forms.Label();
lblPlateNOBAR.Text = lblPlateNO.Text;
lblPlateNOBAR.Location = new Point(right + 20, 80);
foreach(var control in Panel1.Controls)
{
control.Top = control.Top + 150;
}
Panel1.Controls.Add(pbox);
Panel1.Controls.Add(lblPlateNOBAR);
I know it might seem that I'm not answering your question, but you can take little time to know my suggestion too. I don't know what you wanna achieve, but when you want to make such a sophisticated program, it's a better practice that you do all the work needed yourself, not relying on Windows Forms Controls. Trying to add, remove, change location of lots of controls will reduce the application performance very much. I suggest that you draw, for example your pictures, yourself, using Graphics and Image objects and Paint event. Also handle things like clicking and selecting pictures by MouseEvents. It might seem a little hard at first, but after you've done this you have far better performance and flexibility. This becomes more important considering you mentioned you wanna place 200 pictures in the panel. This also prevents trouble of flickering that appears when you change position of many controls. It's good to mention that to do scrolling in this case, you can place a Panel inside of a Parent Panel and use AutoScroll feature only for the parent panel to handle scrolling. This way you don't have to care about the scrolling anymore.
I have a created a panel.
This has autoscroll = true
At the start i added 6 pictureboxes that are 256x256 with images.
I store the last picturebox location, so that i know where to put a new picturebox.
I also add a picturebox to the upper right of the panel(location(8744,8744)), so that the panel will stretch to 9000px.
Later on when i scroll around in the panel, i can push a button and add a picturebox to the panel. The problem is that when i set the location of the picturebox and add it to the panel, it comes out totally wrong, visually.
Code for adding more images.
private void addPictureBox(Point pixelCoordinates, Bitmap image)
{
PictureBox pNewImage = new PictureBox();
imagePanel.Controls.Add(pNewImage);
pNewImage.Image = image;
pNewImage.Name = "image_:" + pixelCoordinates.X + "_" + pixelCoordinates.Y;
pNewImage.Location = pixelCoordinates;
pNewImage.Size = new System.Drawing.Size(256, 256);
pNewImage.Visible = true;
pNewImage.BackColor = Color.White;
imagePanel.Update();
}
If i debug and watches the panel, it says that the new picturebox has the location i set, but visually, it's not.
I have noticed that this is what really happens:
The location of the picturebox is from where i have scrolled + location.X.
Anyone got an idea how i can fix this?
Thanks in advance.
If the pictureboxes are being added after you have scrolled away from the coordinates 0,0 you may need to account for this by adding the scroll amount to pixelCoordinates. Try using imagePanel.VerticalScroll.Value and imagePanel.HorizontalScroll.Value in your calculations.