This code is just changing location, not sliding.
I am using this at the moment:
for (int i = 740; i == 740; i++)
{
panel2.Location = new Point(panel2.Location.X - i, panel2.Location.Y);
}
How can I slide the panel slowly?
Now, as I stated in my comment you really need to use float values, so you really need to draw it. However, the current implementation only makes a single iteration. The current loop could have been translated into this:
panel2.Location = new Point(panel2.Location.X - 740, panel2.Location.Y);
Consider a loop like this to slide it out:
for (int i = -(panel2.Width); i < 0; i++)
{
panel2.Location = new Point(i, panel2.Location.Y);
}
That algorithm is assuming that you've set the Location to the - of it's width (e.g. -740x) so that it's simply not visible on the screen. The reverse would hide it.
This will still be a little choppy, but it won't just hide it like your current code.
If you are just going to slide the panel try to do this
Try this code:
Panel panelArray = new Panel[];
Panel panel2 = panelArray[0];
for (int i = 0; i <= 100; i++)
{
panel2.Location = new Point(panel2.Location.X - i, panel2.Location.Y);
System.Threading.Thread.Sleep(10);
}
Related
I would like to display 13 pictureBox, however, it ends up with only the last one visible.
So I was wondering if I did it in a wrong way.
The following code get image from resources folder.
var testP = new PictureBox();
for (int i = 0; i < 13; i++)
{
testP.Width = 65;
testP.Height = 80;
testP.BorderStyle = BorderStyle.None;
testP.SizeMode = PictureBoxSizeMode.StretchImage;
test[i] = getImage(testP, testPTemp[i]);
}
The following code is trying to display 13 pictureBox with shifting location.
These two codes segments should be able to perform the action.
test = new PictureBox[13];
for (var i = 0; i < 13; i++)
{
test[i].Image = (Image)Properties.Resources.ResourceManager.GetObject("_" + testTemp[i]);
test[i].Left = 330;
test[i].Top = 500;
test[i].Location = new Point(test[i].Location.X + 0 * displayShift, test[i].Location.Y);
this.Controls.Add(test[i]);
}
Here is the getImage()
private PictureBox getImage(PictureBox pB, string i) // Get image based on the for loop number (i)
{
pB.Image = (Image)Properties.Resources.ResourceManager.GetObject("_" + i); // Get the embedded image
pB.SizeMode = PictureBoxSizeMode.StretchImage;
return pB;
}
I'm pretty sure there are all PictureBox Controls but they have all the same location so they are lying above each other. That's why only the last one is visible to you.
I think you should replace the 0 with the i variable.
test[i].Location = new Point(test[i].Location.X + i * displayShift, test[i].Location.Y); this.Controls.Add(test[i]);
It's hard to tell the exact problem based off the code you've provided. One possible issue could be that when you are creating the PictureBoxes you only create a single instance before the for loop and then fill the array with references to that instance. Another possibility is that when you're calculating the X position of the controls, you're multiplying by 0 which will always result in 0 (meaning all the controls are at location 330).
Below is code that will achieve basically what you're trying but without all your code I can't give you a more specific example.
In Your Class
const int PICTURE_WIDTH = 65;
const int PICTURE_HEIGHT = 85;
Inside You Function
//Loop through each image
for(int i = 0; i < testTemp[i].length; i++)
{
//Create a picture box
PictureBox pictureBox = new PictureBox();
pictureBox.BorderStyle = BorderStyle.None;
pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
//Load the image date
pictureBox.Image = (Image)Properties.Resources.ResourceManager.GetObject("_" + testTemp[i]);
//Set it's size
pictureBox.Size = new Size(PICTURE_WIDTH, PICTURE_HEIGHT);
//Position the picture at (330,500) with a left offset of how many images we've gone through so far
pictureBox.Location = new Point(330 + (i * PICTURE_WIDTH), 500);
//Add the picture box to the list of controls
this.Controls.Add(pictureBox);
}
If you need to keep a list of the picture boxes, just create a new list before the loop and add each pictureBox to the list inside the loop. If the control/window you're adding these PictureBoxes to needs to scroll left or right to see all the images set the AutoScroll property to true.
Background
I have a tab which is made active if there is more than one record returned from a query on my database.
For each record returned I would like a set of labels created and placed on the tab. For example if there are 8 records I would like 8 labels created.
Question
My loop only creates one label, even though my count is showing I have 8 records? Not sure why?
How do you create labels in a loop 8 times and not have them draw in the same location 8 times? I would them to appear in a horizontal list. Pretty sure the way I have coded the solution ,they will all be drawn in the same place?
Code
for (int i = 1; i <= rowCount; i++)
{
// Create objects
LinkLabel Linklabel1 = new LinkLabel();
Linklabel1.Text += ds.Tables[0].Rows[0]["code"].ToString();
Linklabel1.Location = new Point(10, 50);
Linklabel1.Height = 40;
Linklabel1.Width = 100;
tabControl1.TabPages[0].Controls.Add(Linklabel1);
}
Try something like this out:
for (int i = 0; i < rowCount; i++)
{
// Create objects
LinkLabel Linklabel1 = new LinkLabel();
Linklabel1.Text = ds.Tables[0].Rows[i]["code"].ToString();
Linklabel1.Height = 40;
Linklabel1.Width = 100;
Linklabel1.Location = new Point((i + 1) * 10 + (i * Linklabel1.Width), 50);
tabControl1.TabPages[0].Controls.Add(Linklabel1);
}
If you don't want to explicitly position them by setting the Location() property, consider putting a FlowLayoutPanel on the TabPage and added the controls to that instead. Then they will positioned automatically for you.
I have a few buttons to add on the form. In the code I'm setting up some button properties:
class DigitButton : Button
{
private static int digitBtnTag;
public DigitButton()
: base()
{
this.Size = new Size(30, 30);
this.Tag = digitBtnTag;
this.Text = (this.Tag).ToString();
this.Margin = new Padding(2);
this.Padding = new Padding(2);
digitBtnTag++;
}
}
In the MainForm.cs I have
for (int i = 0; i < dgtBtns.Length; i++)
{
dgtBtns[i] = new DigitButton();
dgtBtns[i].Click += new EventHandler(this.digitButtonClick);
digitPanel.Controls.Add(dgtBtns[i]);
}
So when I launch a program I see all my buttons in the one place: (0;0) on digitPanel despite property Margin. So why don't all these buttons automaticly "push" each other in the different directions? And how to make it?
Have you tried using a FlowLayout Panel ?
Also, this video might help:
Windows Forms Controls Lesson 5: How to use the FlowLayout Panel
that's not the way controls works in c#. i'm guessing you programed at java a bit because the layout in jave works that whay, but in c# just do
for (int i = 0; i < dgtBtns.Length; i++)
{
dgtBtns[i] = new DigitButton();
dgtBtns[i].Location = new Point(50, 50 * i); // Multiplying by i makes the location shift in every loop
dgtBtns[i].Click += new EventHandler(this.digitButtonClick);
digitPanel.Controls.Add(dgtBtns[i]);
}
you'll have to figure out the location parameters by trying and see
You need to define Left and Top then add the button height or width each time you loop to position your buttons correctly i.e.
int bTop=0;
int bLeft=0;
for (int i = 0; i < dgtBtns.Length; i++)
{
dgtBtns[i] = new DigitButton();
dgtBtns[i].Click += new EventHandler(this.digitButtonClick);
dgtBtns[i].Top = bTop;
bTop += dgtBtns[i].Height;
digitPanel.Controls.Add(dgtBtns[i]);
}
I am creating Conway's Game of life in C# and everything works fine, except the refreshing of the panel to display the next generation. I can draw to the panel to establish grid lines for the cells, place and destroy "life" using simWindow_Paint and simWindow_MouseClick but at present i cannot update it.
private void updateGame(){
int living = 0;
int dead = 0;
for(int i = 1; i < gameHeight; i++)
for (int j = 1; j < gameWidth; j++){
//set cell location and size
Rectangle cell = new Rectangle();
cell.Height = cell.Width = 9;
int X = j - 1;
int Y = i - 1;
cell.X = Convert.ToInt32(X * 10 + 1);
cell.Y = Convert.ToInt32(Y * 10 + 1);
using (Graphics g = this.simWindow.CreateGraphics()){
if (gameArray[i, j] == true){
Brush brush = new SolidBrush(Color.Red);
g.FillRectangle(brush, cell);
++living;
} else {
Brush brush = new SolidBrush(Color.White);
g.FillRectangle(brush, cell);
++dead;
}
}
}
}
I am not sure if what i am attempting to do is possible in C#, I have already done this in Pascal, but i am not sure if C# works the same way...
Difficult to say with what you've shown us, but I suspect the problem might be in your simWindow_Paint method. This is (presumably) responding to the paint event for your panel and I suspect what you are doing is overwriting (or over painting) all the drawing you are doing in your updateGame() method.
All the drawing should be done in your paint handler. So you paint handler should know the state of the game and draw it accordingly. Your updateGame() method should just update the state of the game and then invalidate the panel (forcing a repaint).
I recommend you review the following documentation on custom painting in WinForms: http://msdn.microsoft.com/en-us/library/kxys6ytf.aspx
I'm playing around with WinForms and would like to add alot of Labels with a border so to create some sort of grid. Now, adding the Labels is easy enough:
for (int i = 0; i < 60; i++)
{
for (int j = 0; j < 60; j++)
{
var label = new Label();
label.BorderStyle = BorderStyle.FixedSingle;
label.SetBounds(i * 10, j * 10, 10, 10);
this.Controls.Add(label);
}
}
But this is really, really slow. I can almost see each of the squares being drawn individually. When creating an array of controls and adding them using Controls.AddRange() the same thing happens.
Now since I'm drawing 3600 controls, I can imagine it being somewhat slow, but I can't help but think there's a better way to do this.
When I time the Control.AddRange() statement, the Stopwatch tells me it's taking about 1600ms. The actual drawing seems to take a bit longer.
Is there any way to work around this and keep an application with alot of controls snappy and responsive?
Do you NEED the individual controls?
With tasks like this I usually override onpaint in a usercontrol and draw the text and boxes myself.
Then if you need user input, just position a single textbox ontop of your custom text.
Take a hint from your Form1.Designer.cs :
this.SuspendLayout();
// code to add Labels
this.ResumeLayout(false); // maybe use true
Consider creating a List<Control>, adding the controls to that in your loop. Then add the controls to the form's controls collection only one time after your loop using this.Controls.AddRange() to fill the controls collection.
You can try add labels to new Panel, an then Panel add to Form:
var NewPanel = new Panel
{
Dock = DockStyle.Fill
};
for (int i = 0; i < 60; i++)
{
for (int j = 0; j < 60; j++)
{
var label = new Label();
label.BorderStyle = BorderStyle.FixedSingle;
label.SetBounds(i * 10, j * 10, 10, 10);
NewPanel.Controls.Add(label);
}
}
this.Controls.Add(NewPanel); // (Form).Controls.Add(NewPanel);