Question

I have a C# winform which displays snapshots from a camera. The form has four PictureBox controls and When an image is taken it is placed into pictureBox1 and the previous images are bumped along to 2,3 and 4. Under each picture box is also a label which displays the time stamp and the order number (each image is given a number 1-4, that stays with it until it is bumped off in which the newest image takes that number). Currently I am doing it like below. However I feel this is very inefficient and will cause me problems later on if I decide to add key down events to change the backcolors of some of the labels (to indicate status).

Does anyone know of a better way to do this?

if (count > 4)
{
    count = 0
}

count ++;

pictureBox4.image = pictureBox3.image;
pictureBox3.image = pictureBox2.image;
pictureBox2.image = pictureBox1.image;
pictureBox1.imagelocation = (@"http://192.168.X.X/image.cgi")

label4.Text =label3.text;
label3.text = label2.text;
label2.text = label1.text;
label1.text = count.ToString()+ " " + datetime.now();
Was it helpful?

Solution

I could create a new Control, most likely a Panel that contains all of these UI elements in it (PictureBox, Label, anything else). Have a constructor for your Control that takes a URL of the image. Load the image into your PictureBox, and set your label.

Have all of that logic encapsulated in your Control. So when a new one is added, you just create the new Control, and remove the last one in your row, and move the .Left properties of the 3 remaining to their new locations.

Don't forget to implement IDisposable, and Dispose of the Controls when they're removed to free up the resources of displaying the images.

EDIT

If it's not there already, you can provide references back to the top Control in each of your inner Controls (PictureBox and Label), and even to your main form in your top Control by passing this as a parameter in the constructor as well and setting a private member variable inside those controls. That way, when someone clicks on the PictureBox, you can go up the line to this.Parent and get your outer Control. You could even have that reference to your Main Form (hopefully a Panel in there that holds your 4 of these objects). That could be this.Parent.Parent to call a method on there. (I think there's already a public property of Parent on all Controls, so that's fine.)

A little bit of quick coding:

You have your main Form (mainForm). In there is a Panel (picturePanel). picturePanel holds your 4 new Panels, which we'll call customPanel. Each customPanel has a PictureBox (imageBox), and Label (fileNameLabel).

Your customPanel constructor would look like this:

public partial class CustomPanel : Panel {
    private PictureBox _imageBox;
    private Label _fileNameLabel;

    public CustomPanel() {} // This is most likely tied into the code behind file. Sorry, It's been a while since I've done WinForms

    public CustomPanel(string imageFileName, Panel parent) {
        // Set the source for the PictureBox.
        // Set the Text of the label.
        _parent = parent;
    }
}

Continue with this down the line through the PictureBox and Label. Then in your events, you have your PictureBox work up the chain. To find picturePanel. If you want to get really fancy, you could have that derive from Panel as well and just add a public property that handles all of the switching around of which customPanel sent the message.

So down in your PictureBox event, you could have a line of code like this:

if (this.Parent.Parent is PicturePanel) {
    ((PicturePanel)this.Parent.Parent).RemovePicture(this.Parent);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top