I am trying to do the following action with pictureboxes:
Search for a picturebox that has a special image, my method for this returns a number of the box that has this image.
Example:
if (picturebox1.Tag == "special") {
return 1; //returns value 1 as in picturebox1 contains it.
}
Now when I click on pictureBox2 I want it to switch with the picturebox that contains the special picture (I have a total of 10 pictureboxes with pictures, only one box contains a special one)
Click event on picturebox2:
private void pictureBox2_Click(object sender, EventArgs e)
{
performSwitch(2); //2 meaning picturebox "2"
}
Method it calls:
public void performSwitch(int pictureBoxWaarde)
{
switch (pictureBoxWaarde)
{
case 2:
pictureBox10.Image = pictureBox2.Image; //else picture overwrites
pictureBox2.Image = pictureBox1.Image;
pictureBox1.Image = pictureBox10.Image;
break;
}
}
This code works however I dont want to make TONS of if-else statements for every combination there is.. So to make it 'smart' I will need something like this:
public void performSwitch(int pictureBoxWaarde)
{
switch (pictureBoxWaarde)
{
pictureBox10.Image = pictureBox2.Image; //else picture overwrites
pictureBox2.Image = pictureBox"+findBlackBox+".Image;
pictureBox"+findBlackBox()+".Image = pictureBox10.Image;
break;
}
}
If this would work it would get the special box number and work without the need of lots of if-else. How would I do this?
I'm not sure whether I fully understand what you're trying to achieve, but you can always find a control by its name.
Let's say that you have a variable string m_specialPictureBoxName; that always contains the name of the current special picture box, you could do the following:
public void performSwitch(int pictureBoxWaarde)
{
// Get current special picture box
PictureBox currentSpecial = this.Controls.Find(m_specialPictureBoxName, true) as PictureBox;
// Get new special picture box
m_currentPictureBoxName = String.Format("pictureBox{0}", pictureBoxWaarde);
PictureBox clicked = this.Control.Find(m_currentPictureBoxName, true) as PictureBox;
// Swap images
Image temp = currentSpecial.Image;
currentSpecial.Image = clicked.Image;
clicked.Image = temp;
}
Also I'm swapping the image without using the temporary pictureBox10 assignment - I'm not sure whether you want pictureBox10 to get the image. If you do, you can replace it with your previous code instead of the Image temp = ...line.
Assign all the PictureBox event handlers to a single method.
Write the method like this
private void ApictureBox_Click(object sender, EventArgs e)
{
var clickedPicture = sender as PictureBox;
// iterate through all picture controls of the current form
for (var pic in this.Controls.OfType<PictureBox>())
if (pic.Tag=="special")
{
var temp = clickedPicture.Image;
clickedPicture.Image = pic.Image;
pic.Image = temp;
}
}
For the first step, you can either do it manually, or use a similar loop to assign the event handlers in the form constructor.
Related
Here is my question:
Im making a booking cinema system in c#, windows form
Let's say i have 5 columns of 5 rows of pictureboxes that on form load get their value, avaliable or not from the database.
The user then click on the seat he wants (and the image of the pictuebox change) and press a submit button.
How i can check the image of every picturebox (to determine if he want this seat or not) together?
I can do something like this
if (picturebox11.image=="seatchecked"){seats[]+=11;}
if (picturebox12...
But im wondering if there is another faster way to do it. (the position of the pictureboxes is fixed if that helps)
I have done this so far:
private void button1_Click(object sender, EventArgs e)
{
List<PictureBox> pb = new List<PictureBox>();
pb.Add(seat11);
pb.Add(seat12);
pb.Add(seat13);
pb.Add(seat14);
pb.Add(seat15);
pb.Add(seat21);
pb.Add(seat22);
pb.Add(seat23);
pb.Add(seat24);
pb.Add(seat25);
pb.Add(seat31);
pb.Add(seat32);
pb.Add(seat33);
pb.Add(seat34);
pb.Add(seat35);
for (int i = 0; i < 20; i++) {
pb[i].Click += pictureBox_Click;
}
}
void pictureBox_Click(object sender, EventArgs e)
{
this.pictureBox.Image = ArgyroCinema.Properties.Resources.seatred;
}
Store each PictureBox in a list and iterate through them. Also, when the user selects/deselects a seat, change the Tag property of the PictureBox as, at the moment, you're trying to compare a string to an Image (picturebox11.Image returns an Image object).
List<PictureBox> pb = new List<PictureBox>();
pb.Add(pictureBox1);
pb.Add(pictureBox2);
//etc..
Alternatively, you can use the methods suggested here to get all PictureBox objects in your form to save you having to type it out above.
Then just iterate through them and read their Tag property. In this case I've used true to represent that they want the seat but Tag is an object type, so you can use whatever type you like.
foreach(PictureBox p in allPictureBoxes)
{
if((bool)p.Tag == true)
{
//seat wanted
}
else
{
//seat not wanted
}
}
Update from comments
void pictureBox_Click(object sender, EventArgs e)
{
PictureBox pb = sender as PictureBox;
if(pb != null)
pb.Image = ArgyroCinema.Properties.Resources.seatred;
}
I am writing a screensaver program in C#. And I want it to do the following:
Start with a text. After about 3 seconds or more, hide the text and show an image. After the next 3 seconds, hide the image show the text and keep going round the loop until the user does something that exits the screensaver.
What I have done:
I started with a simple textlabel and a timer control. I was able to get the textlabel change positions on screen after every 3 seconds. I updated my code to include a picturebox, and in my timer_tick method, I inserted an if-else statement to check, when the method is called,
if the textlabel is shown, hide it and show the picturebox.
else if the picturebox is shown, hide it and show the textbox. Code is shown below:
private void Form1_Load(object sender, EventArgs e)
{
Cursor.Hide();
TopMost = true;
moveTimer.Interval = 3000;
moveTimer.Tick += new EventHandler(moveTimer_Tick);
moveTimer.Start();
}
private void moveTimer_Tick(object sender, System.EventArgs e)
{
//Move text to new Location
//textLabel.Left = rand.Next(Math.Max(1, Bounds.Width - textLabel.Width));
//textLabel.Top = rand.Next(Math.Max(1, Bounds.Height - textLabel.Height));
if (pictureBox1.Enabled == true)
{
pictureBox1.Hide();
textLabel.Show();
}
if (textLabel.Enabled == true)
{
textLabel.Hide();
pictureBox1.Show();
}
}
Here's the problem:
WHen I run the screensaver program, the screen starts with the text, changes to the picture after 3 seconds and stops there.
What do I do to get it moving in a continous loop, showing/hiding the textlabel or picturebox?
Have I implemented this in the right way?
Please clear and concise explanations/answers will be highly appreciated.
Thanks!
Perhaps you could keep the state in a variable that you can switch
private bool state = false;
private void moveTimer_Tick(object sender, System.EventArgs e)
{
//Move text to new Location
//textLabel.Left = rand.Next(Math.Max(1, Bounds.Width - textLabel.Width));
//textLabel.Top = rand.Next(Math.Max(1, Bounds.Height - textLabel.Height));
if (state)
{
pictureBox1.Hide();
textLabel.Show();
}
else
{
textLabel.Hide();
pictureBox1.Show();
}
state = !state;
}
How about something like this?
Enabled says whether the object can receive input.
Visible is what says if its visible or not.
You see it change once and only once because all the objects are enabled. The first if succeeds, hiding the picture and showing the text. But then the second if also succeeds, showing the picture and hiding the text. Since this is all in one event callback, you never see the first if happen, because the second overrides it.
As you're realizing in the comments, the answer is to not check enabled. Instead, check Visible. Make sure to use an else as well, otherwise you may still get the same issue of both being true.
private void moveTimer_Tick(object sender, System.EventArgs e)
{
//Move text to new Location
//textLabel.Left = rand.Next(Math.Max(1, Bounds.Width - textLabel.Width));
//textLabel.Top = rand.Next(Math.Max(1, Bounds.Height - textLabel.Height));
if (pictureBox1.Visible == true)
{
pictureBox1.Hide();
textLabel.Show();
}
else
{
textLabel.Hide();
pictureBox1.Show();
}
}
For a school project, I have to make a table reservation system,
I made the following (just a small part).
PictureBox[] pb = new PictureBox[70] { pictureBox1, pictureBox2, pictureBox3,etc.. };
foreach (PictureBox p in pb)
{
p.BorderStyle = BorderStyle.Fixed3D;
p.BackColor = Color.White;
p.MouseEnter += new EventHandler(mouseOn);
p.MouseClick += new MouseEventHandler(mouseClick);
}
private void mouseOn(object sender, EventArgs e)
{
((PictureBox)sender).BackColor = Color.Green;
}
private void mouseClick(object sender, EventArgs e)
{
reservationForm rf = new reservationForm();
rf.ShowDialog();
}
I chose for pictureboxes to represent the tables, the default BackColor is white, and when the mouse enters the BackColor turns green.
When you click on 1 of those PictureBoxes my reservationForm will open, this is where you can further fill in the details to book the table.
but the part where I get stuck now is that I don't know on my reservation form which PictureBox I clicked, so I need to get something like the index of the PictureBox array.
How do I fix this?
You know how to do it! :)
You're already doing it correctly on the mouseOn event handler. Just do the same cast of the sender parameter.
private void mouseClick(object sender, EventArgs e)
{
PictureBox clickedBox = (PictureBox)sender;
reservationForm rf = new reservationForm();
rf.ShowDialog();
}
If you need the index, you can use Array.IndexOf, assuming your pb array is a class level variable and not a method local.
int index = Array.IndexOf(pb, clickedBox);
Check sender
private void mouseClick(object sender, EventArgs e)
{
PicterBox pb = (PicterBox)sender;
...
}
In your "MouseOn" you already use (PictureBox)sender to get a reference to the picturebox.
Then you can walk through the array to compare the picturebox at a specific index to the clicked one. When you have a match, you found the index.
var clicked = (PictureBox)sender;
int index = 0;
while (index < pb.Length && pb[index] != clicked) index = index+1;
// now index is either 70 (if not found) or the position you want (0..69)
Maybe you can set in for cycle a name at each picturebox equals at the corrispondent index. So in the listener u can use
PicterBox pb = (PicterBox)sender;
and get the name that is the index.
You have many options. I will suggest some of them:
Create a public class variable or property and store the current selected Picturebox on the click event, so you can access it from the form;
Pass in the Picturebox for the constructor of the form (creating a constructor that accepts this info and stores it in an internal variable).
I want to use a wheel to change (for example) 30 buttons' background image each time a form loads.
I cannot use this:
for(int i=1;i<=30;i++)
{
button i .backgroundimage=image.fromfile("URL");
}
What should I do?
There are many possible interpretations of your problem. Why can't you use your code? There are also different solutions for your problem.
As example:
public Form1() // Constructor
{
InitializeComponent(); // Ensure all controls are created.
List<Button> buttons = new List<Button>(30);
buttons.Add(mybutton1)
buttons.Add(mybutton2)
// Go futher with all your buttons.
}
private void Form1_Load(object sender, System.EventArgs e) // Create a load event
{
foreach(Button button in buttons)
{
button.BackgroundImage = Image.FromFile(path);
// Note: The file remains locked until the Image is disposed!
}
}
Well you could use something like this assuming this code executes in a Form_Load and the buttons Parent control is your form. Have in mind that you should supply the real path to your image that you want to set as a background image
string path = "rootNameOfTheImage";
int counter = 0;
foreach(Control ctrl in this.Controls)
{
if(ctrl is Button)
{
Button btn = (Button)ctrl;
if(/* test if this button should be used */)
{
btn.BackgroundImage=Image.FromFile(path + counter++.ToString() + ".jpg");
}
}
}
i have picturebox with picture cb.
PBr1_1.Image = new Bitmap(#"Logos\\Images\\cb.png");
I'd like to change image to cg.png and do some action when i click this image. I was trying something like that but without success:
private void PBr1_1_Click(object sender, EventArgs e)
{
if (PBr1_1.Image.ToString() == "cb.png")
{
PBr1_1.Image = new Bitmap(#"Logos\\Images\\cg.png");
// Do some stuff.
}
}
And then do the same when i click image with cb. To visualise this cb is black circle button image, and cg is green one.
How can i do this?
Jason is right, you should use some kind of temporary storage to save your current bitmap.
The Tag property is useful in this kind of situations. Here a sample code: (Without error handling)
somewhere in your load event
PBr1.Tag = "cb.png";`
PBr1_1.Image = new Bitmap(Path.Combine("Logos\\Images", PBr1.Tag.ToString());
and then in button click
private void PBr1_1_Click(object sender, EventArgs e)
{
string imgPath = "Logos\\Images";
PBr1_1.Image.Dispose();
PBr1_1.Tag = (PBr1_1.Tag == "cb.png" ? "cg.png") : "cb.png") ;
Bitmap bm = new Bitmap(Path.Combine(imgPath, PBr1.Tag.ToString());
PBr1_1.Image = bm;
}
Are you sure that "PBr1_1.Image.ToString()" really returns only the image name?
Maybe you should check this by writing PBr1_1.Image.ToString() to console or something like that