In this program im writing I use a function to create multiple instances of a PictureBox. This is the code:
public void serverCard()
{
//Definitions
PictureBox cardBack = new PictureBox();
//Specifics for card
cardBack.Size = new Size(cardSizeX, cardSizeY);
cardBack.BackColor = Color.White;
cardBack.Left = startX;
cardBack.Top = startY;
serverArea.Controls.Add(cardBack);
//differences in pos
startX += cardBack.Width + 5;
if (startX > this.Width - cardSizeX)
{
startY += cardBack.Height + 5;
startX = 5;
}
}
How would I access a specific instance of the PictureBox.
For Example: I create 5 PictureBoxes called "cardBack" using this function. I want to change the position of the second Picture Box that was created, how would I go about this.
1) You could either give each PictureBox a different name (may be "cardBack" + ID_in_int)
int picBox_ID = 1;
public void serverCard()
{
PictureBox cardBack = new PictureBox();
cardBack.Name = "cardBack" + picBox_ID;
picBox_ID++;
and pull them out of the Controls by name:
PictureBox temp = serverArea.Controls.OfType<PictureBox>().FirstOrDefault(x=>x.Name == "cardBack2");
2) or you could have a separate collection of type: List<PictureBox> where you would store them additionally
List<PictureBox> picCollection = new List<PictureBox>();
public void serverCard()
{
PictureBox cardBack = new PictureBox();
picCollection.Add(cardBack);
and access them in the way you want. May be the order could be of interest.
3) another possibility could be to create a new class that has a property of type PictureBox and another property int ID. You could have a collection filled with these objects and each object could have a unique ID and the corresponding PictureBox. You can still put the picture boxes into the Controls and filter the collection according to your needs.
Create a method that will return instance of PictureBox
public PictureBox CreatePictureBox ()
{
// your code from question here
}
then define a field in your form
private Dictionary<string, PictureBox> pboxes = new Dictionary<string, PictureBox>();
Any time you want to create a new PictureBox put it inside pboxes collection:
pboxes.Add("box1", CreatePictureBox());
Now you can access to your boxes like this:
pboxes["box1"].Width += 20;
Related
My code in C# displays picture boxes vertically where the second picture box is below the first one instead of displaying the second picture box horizontally next to the first such that when the width of the visible form overflows. the code creates a new row and continues to create picture boxes. The code reads image file paths from a folder and initializes an array of picture boxes based on the count of the images. The goal is to create a grid of picture boxes for displaying the images. How can I update the logic of the app to make it achieve the desired output.
public class ImageGrid:Form {
//declare the folder name that contains the complex images
private string _folder = "./Complex"; //declare the array of picture boxes to display in the form
private PictureBox[] _image_grid;
private List<string> _paths= new List<string>();
public ImageGrid() {
//set a title for the form
Text = "Confidence Level Checker";
//make the screen full
FormBorderStyle =
FormBorderStyle.None;
WindowState =
FormWindowState.Maximized;
//read all the image names in the folder
if (Directory.Exists(_folder)) {
//list all the files in the folder
string[] files =
Directory.GetFiles(_folder);
if (files != null && files.Length > 0) {
//add the paths to the list
foreach (var path in files) {
_paths.Add(path);
}
//create an array of picture boxes based on the file count
_image_grid = new PictureBox[files.Length];
//declare the size of each picture box
int width = 300; int height = 250;
int x = 20; int y = 20;
foreach (string path in _paths) {
PictureBox box = new PictureBox()
{
Size = new Size(width, height),
Location = new Point(x,y),
Image = Image.FromFile(path),
SizeMode = PictureBoxSizeMode.StretchImage
};
//add the picture box to the form
this.Controls.Add(box);
//update the location to draw the picture box
x += 320;
if (x + 300 > ClientSize.Width) { x = 20; y += 270; }
}
}
}
}
You can use a FlowLayoutPanel() instead to make this simpler.
Then ensure (in the form designer) that the property FlowDirection is set to LeftToRight.
You can also do this in code:
myFlowLayoutPanel.FlowDirection = FlowDirection.LeftToRight;
You add controls to a FlowLayoutPanel the same way you do to a standard Panel:
myFlowLayoutPanel.Add(someControl);
I have a windows form in C# project that keeps some information. I created a bunch of textbox and combobox dynamically, depend upon user input.
So here there is two rows since user has given the input as 2. All the components in the image are dynamically created. For each component i have created a class to set the property and its behaviour.
Now the issue is I need to traverse the component using tab.
When i tried to set tabindex = 1 for the first textbox and tabindex = 2 for the second textbox. I'm traversing the components vertically like mentioned below
Actual Output : enter image description here
The code in which i have added are following.
public class addDynamicCptboxComponents : add_components
{
public override void add_dynamic_components(int getNoOfTxtBox, int pointX, int pointY, Form1 f)
{
TextBox txtBox = new TextBox();
f.panel1.Controls.Add(txtBox);
txtBox.Location = new Point(pointX, pointY);
txtBox.Size = new System.Drawing.Size(75, 23);
f.panel1.Controls.Add(txtBox);
txtBox.Name = "Add_txtBox" + getNoOfTxtBox;
//assigned the tabindex as 2 for the second textbox
txtBox.TabIndex = 2;
}
}
public class addDynamicDateofServiceComponents : add_components
{
public override void add_dynamic_components(int getNoOfTxtBox, int pointX, int pointY, Form1 f)
{
TextBox txtBox = new TextBox();
f.panel1.Controls.Add(txtBox);
txtBox.Location = new Point(pointX, pointY);
txtBox.Size = new System.Drawing.Size(75, 23);
f.panel1.Controls.Add(txtBox);
txtBox.Name = "Add_dos_txtBox" + getNoOfTxtBox;
//assigned the tabindex as 1 for first textbox
txtBox.TabIndex = 1;
}
}
But what i need is , I need to traverse the components horizontally as mentioned below.
Expected Ouput: enter image description here
The Requried tab order is specified in the above image.
Guessing from the name of your class you are adding rows dynamically to your form. But since you are hard coding the tab index the result per row looks like in your expected output. This means by tabbing you go from index 1 to index 1 to index 2 to index 2 and so on and so forth.
I'd advise you to have an incrementing tab index stored somewhere in your application which is incremented after it is assigned to a new dynamically created control.
As a really simple example I created a fresh forms project which just has two buttons. The first one adds a new textbox and the second button switches into a new row. And in this example everything has the tab index you require. The code behind looks like this:
public partial class Form1 : Form
{
private int currentX = 0;
private int currentY = 0;
private const int tbWidth = 75;
private const int tbHeight = 23;
private int currentTabIndex = 0;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var textBoxOne = new TextBox();
this.Controls.Add(textBoxOne);
textBoxOne.Location = new Point(this.currentX, this.currentY);
textBoxOne.Size = new Size(tbWidth, tbHeight);
textBoxOne.TabIndex = currentTabIndex;
textBoxOne.Text = $"{currentTabIndex}";
currentTabIndex++;
this.currentX += tbWidth + 5;
}
private void button2_Click(object sender, EventArgs e)
{
currentY += tbHeight + 5;
currentX = 0;
}
}
Please bare in mind this is just a simple example. I could help you better in the context of your application if I knew more about it.
I'm working on C# windows form. I have an array of picturebox, displayed on the form. The array has the size of 13, and they're all side by side. How can I make it so that when I click on a picturebox, it is moved up by let's say +20 on y.
My code to make the picture boxes. The pb1 and p1 are declared above
void print_Deck(int x, int y, double[] a){
double n;
for (int i = 0; i < 13; i++)
{
pb1[i] = new PictureBox();
// pb1[1].Image = Properties.Resources.img1;
pb1[i].Visible = true;
pb1[i].Location = new Point(0, 0);
this.Size = new Size(800, 600);
pb1[i].Size = new Size(46, 65);
pb1[i].SizeMode = PictureBoxSizeMode.StretchImage;
pb1[i].Location = new Point(x, y);
n= a[i];
im = face(n);
pb1[i].Image = im;
this.Controls.Add(pb1[i]);
x = x + 20;
}
}
You can try adding Click event on your Picturebox then you can try this code on the Click function.
You can manipulate the location by using Top propery.
Picturebox.Top -= 20; // move the picture box upward
or
Picturebox.Top += 20; // move the picture box downward
or use the .Location = New Point(X,Y)
Picturebox.Location = new Point(Picturebox.Location.X, Picturebox.Location.Y + 20);
Here's how you add the EventHandler to your picturebox.
Picturebox.Click += new System.EventHandler(this.Picturebox_ClickFunction);
then create a fucntion with the name Picturebox_ClickFunction
private void Picturebox_ClickFunction(object sender, EventArgs e)
{
PictureBox pb1 = (PictureBox)sender; // you need to cast(convert) the sende to a picturebox object so you can access the picturebox properties
}
then you can use the code I provided above.
You can try PictureBox.Top property with Anchor property
or use PictureBox.Location.
You could register the PictureBox's 'Click' event to adjust the 'Margin' property by the required amount
i am trying to make macrosubstitution in c#. Actually i'm trying to learn c#. I am experienced in Visual fox.
Anyway this what i need:
let's say i am trying to add a new control programmaticaly:
ProgressBar progressBar1 = new ProgressBar();
progressBar1.Size = new System.Drawing.Size(516, 23);
progressBar1.Location = new Point(10, 36);
groupBox4.Controls.Add(progressBar1);
now i need to know a way how to replace the name o f the control (progressBar1) and tke the name for an string variable so i could create using a for statement more then one progress bar
?
any ideea?
progressBar1 is not the name of the control. Is the name of a variable of type ProgressBar used to work with the current instance of a ProgressBar.
Every class derived from Control has a property called Name of string type.
int xPos = 10;
int yPos = 36;
// Add 10 progressbars to the groupbox control collection
for(x = 0; x < 10; x++)
{
yPos = yPos + (x * 30);
ProgressBar progressBar1 = new ProgressBar();
progressBar1.Name = "pgb" + x.ToString();
progressBar1.Size = new System.Drawing.Size(516, 23);
progressBar1.Location = new Point(10, yPos);
groupBox4.Controls.Add(progressBar1);
}
To retrieve one of your added progress bars you can simply use the Controls object collection of the groupbox.
ProgresBar pb = groubBox4.Controls["pgb1"] as ProgressBar;
pb.Increment(1);
You have to put the code inside a for loop to create more than one instance of the progress bar, if you want to keep a reference of the items you can store them into a Dictionary, for example :
Dictionary<int, ProgressBar> progressBars = new Dictionary<int, ProgressBar>();
for(int i = 0; i < someValue; i++) {
ProgressBar progressBar = new ProgressBar();
progressBar.Size = new System.Drawing.Size(516, 23);
progressBar.Location = new Point(10, 36);
groupBox4.Controls.Add(progressBar);
progressBars.Add(i, progressBar);
}
So, now you can get back a desired progressbar looking in the dictionary, by the index(or by something else you define as key) ...
Example of getting back the progressbar with index 3(through the indexer) :
ProgressBar bar = progressBars[3];
bar.Value = //Assign some value
I am having some issues making my label show up in the gui... any thoughts?
private void addNewExcerciseButton_Click(object sender, EventArgs e)
{
int y = 305;
int x= 61;
string tempExcercise = excerciseTextBox.Text;
excerciseTextBox.Clear();
Label[] excerciseLabels = new Label[numExercises];
for (int i = 0; i < numExercises; ++i)
{
excerciseLabels[i] = new Label();
excerciseLabels[i].Text = ToString("{0}. {1}", i + 1, tempExcercise);;
excerciseLabels[i].Location = new System.Drawing.Point(x, y);
x += 10;
y += 10;
++numExercises;
}
}
thanks in advance.
numExercises is global.
You have to add each new Label to the collection of Controls contained by a visible Control (such as your Form). You're creating and setting them up, but they aren't part of the GUI yet until they're in the control hierarchy.
Add the following line after setting the location of the label:
this.Controls.Add(exerciseLabels[i]);
You need to add the label to the GUI:
this.Controls.Add(excersizeLabels[i]);
As a side note, there is no point in using an array.