none
How to empty a picture box in c#? RRS feed

  • Question

  • Below is my snippet to show a picture using PictureBox().

                    picMatcheds[picId] = new PictureBox();
                    picMatcheds[picId].Width = 100;
                    picMatcheds[picId].Height = 100;
                    picMatcheds[picId].Location = new Point (700, 100 * picId);
                    picMatcheds[picId].SizeMode = PictureBoxSizeMode.StretchImage;
                    string url = @"http://localhost:8099/image/" + imageDataId;
                    this.Controls.Add(picMatcheds[picId]);
                    WebClient client0 = new WebClient();
                    Uri url0 = new Uri(url);
                    client0.DownloadFile(url0, @"d:\test\testpicfile");
                    picMatcheds[picId].Visible = true;
                    var request = WebRequest.Create(@"d:\test\testpicfile");
                    using (var response = request.GetResponse())
                    using (var stream = response.GetResponseStream())
                    {
                        picMatcheds[picId].Image = Image.FromStream(stream);
                    }
                    picMatcheds[picId].Visible = true;

    It shows a picture successfully. Then, I'd like to empty it. I did it by

    picMatcheds[picId].Image = null;

    It seems working well, but then the trouble came. After emptying it, I'd like to display another picture using the same picMatcheds[picId], thru the original code snippet. This time, the picture can't be shown successfully.

    How come?

    • Moved by CoolDadTx Tuesday, June 18, 2019 1:55 PM Winforms related
    Tuesday, June 18, 2019 7:44 AM

Answers

  • Greetings Stan.

    I think your problem is that, if you use the exact same code the second time through, you are creating another PictureBox and adding it to the controls without removing the original from the controls. That means you have two controls of the same size in the same location, and one of them has no image.

    Try modifying your code to only create the PictureBox once.

                    // If the PictureBox doesn't exist, create it and add it to the controls. Otherwise, use the existing box.
                    if(picMatches[picId] == null)
                    {
                       picMatcheds[picId] = new PictureBox();
                       this.Controls.Add(picMatcheds[picId]);
                    }
                    picMatcheds[picId].Width = 100;
                    picMatcheds[picId].Height = 100;
                    picMatcheds[picId].Location = new Point (700, 100 * picId);
                    picMatcheds[picId].SizeMode = PictureBoxSizeMode.StretchImage;
                    string url = @"http://localhost:8099/image/" + imageDataId;
                    WebClient client0 = new WebClient();
                    Uri url0 = new Uri(url);
                    client0.DownloadFile(url0, @"d:\test\testpicfile");
                    picMatcheds[picId].Visible = true;
                    var request = WebRequest.Create(@"d:\test\testpicfile");
                    using (var response = request.GetResponse())
                    using (var stream = response.GetResponseStream())
                    {
                        picMatcheds[picId].Image = Image.FromStream(stream);
                    }
                    picMatcheds[picId].Visible = true;

    Wednesday, June 19, 2019 3:37 AM

All replies

  • The control shows whatever image you set Image to. If you null it out then it is of course empty. To set it again you'd need to assign it back to the image you had originally. In your cause you're getting that image from a web request. Since you are taking the returned stream and putting it into an image and then assigning that image to the box, as soon as you clear the image you cannot get it back because you didn't store it anywhere.

    If you want to be able to hide and show an image then personally I would recommend you store the image you want to show in a field in your class. Then set the picturebox to that image. Set the picturebox to null when you want to hide it. Alternatively just hide the picturebox and leave the image alone.

    public class MyForm : Form
    {
       protected override void OnLoad ( EventArgs e )
       {
          _image = new Lazy<Image>(LoadImage);      
       }
    
       //To show the image
       private void ToggleImage ( int id, bool show )
       {
          var pic = picMatcheds[id];
    
          pic.Image = show ? _image.Value : null;
       }
    
       private Image LoadImage ()
       {
          var client = new WebClient();
          ...
    
          return Image.FromStream(stream);
       }
    
       private Lazy<Image> _image;
    }

    I notice that you're creating the picturebox and setting the image at the same time. Hopefully you're not doing this in the constructor. I assume you have some logic that is dynamically generating the picturebox so you can fit this code wherever. Also, in your example you are using a test image. I assume that each box may have its own unique picture. In this case you'll need to expand from a single image to a list of images or (more likely) simply attach the image to the business object that this picture box is supposed to represent.

    Note that your stream logic is wrong and will not work properly. Whenever you create an image from a stream using ImageFromStream the stream MUST remain for the life of the image.  In your code you are using a `using` statement around the stream returned from the response. This will clean up the stream which invalidates the image itself. Do not wrap the stream in a using because it has to persist for the life of the image. The image will handle cleaning up the stream.

    Finally, the C# forums is for C#-specific questions only. Please post questions related to Winforms in the Windows Forms forum. I will move this post.


    Michael Taylor http://www.michaeltaylorp3.net

    Tuesday, June 18, 2019 1:55 PM
  • In order to show the image, try this:

       picMatcheds[picId].ImageLocation = @"http://localhost:8099/image/" + imageDataId;

    To clear it, use

       picMatcheds[picId].Image = null;

    Tuesday, June 18, 2019 2:36 PM
  • I tried and found that ...ImageLocation = ... works. It's better than my original solution because it doesn't need to download to a temporary file.

    I also found that it has the same trouble. That's, once picMatcheds[picId].ImageLocation was set as null, the picture can't be shown even picMatcheds[picId].ImageLocation was set to a new picture again.

    Wednesday, June 19, 2019 3:04 AM
  • Greetings Stan.

    I think your problem is that, if you use the exact same code the second time through, you are creating another PictureBox and adding it to the controls without removing the original from the controls. That means you have two controls of the same size in the same location, and one of them has no image.

    Try modifying your code to only create the PictureBox once.

                    // If the PictureBox doesn't exist, create it and add it to the controls. Otherwise, use the existing box.
                    if(picMatches[picId] == null)
                    {
                       picMatcheds[picId] = new PictureBox();
                       this.Controls.Add(picMatcheds[picId]);
                    }
                    picMatcheds[picId].Width = 100;
                    picMatcheds[picId].Height = 100;
                    picMatcheds[picId].Location = new Point (700, 100 * picId);
                    picMatcheds[picId].SizeMode = PictureBoxSizeMode.StretchImage;
                    string url = @"http://localhost:8099/image/" + imageDataId;
                    WebClient client0 = new WebClient();
                    Uri url0 = new Uri(url);
                    client0.DownloadFile(url0, @"d:\test\testpicfile");
                    picMatcheds[picId].Visible = true;
                    var request = WebRequest.Create(@"d:\test\testpicfile");
                    using (var response = request.GetResponse())
                    using (var stream = response.GetResponseStream())
                    {
                        picMatcheds[picId].Image = Image.FromStream(stream);
                    }
                    picMatcheds[picId].Visible = true;

    Wednesday, June 19, 2019 3:37 AM
  • picturebox.initialimage = null; 
    • Edited by amolpb Saturday, July 6, 2019 5:38 AM
    Saturday, June 22, 2019 4:01 AM