views:

237

answers:

2
  1. I want to create a scrollable list of pictures fetched from the internet and give the user the ability to click on it. How do i go about doing it in WinForms/C#? Is it possible to add picturebox control/ controls to the listBox?

  2. I tried adding a list of picturebox into UserControl with AutoScroll set to true, which will give me a feel like using a listBox, Is this a right approach?

  3. I also tried setting the ImageLocation of the pictureBox to a URI of the image and then called Load() to load the image, it did work, however my Form is freezing up! How do i go on updating each of the picturebox in a sequential way without freezing my form?

Thank you, Azlam

+1  A: 

I'll answer your third question first, becuase that's the only one I REALLY know the answer to. There's a LoadAsync() method on the picture box that will load the image in a seperate thread and won't hang your app.

As for the other questions, I too would most likely start with a user control and put the images there. The only thing I can suggest would be to first create a user control that has a picture box, and maybe a multiline textbox or richtextbox next to it. Turn off the border on the textbox, and have a slight border around the entire control. This will allow you to display the image, with some text next to it. Then, your actual final control will just be a collection of these controls with the ability to add them as needed.

--my 2 cents...

BFree
Thanks, let me try the loadAsync() method, i am doing the exact way which you have mentioned
Azlam
hey does this approach require the Base Control to be placed in a MDI like Application? Will it prevent the app from freezing up?
Azlam
A: 

Do you mind scrolling vertically?

I would start with the DataGridView control as a base and create the following implementation:

1) Create custom column and celltype deriving from DataGridViewImageColumn. You could call them "CronosNetImageColumn", "CronosNetImageCell".

2) Create a class "CronosImageDetails" to hold the cell data (include properties for display text and image url). This will be passed in as the value for each cell. Ex:

ImageGrid.Rows.Add(new CronosImageDetails { DisplayText="Day at the Beach", ImageURL="http://...beach.jpg" });

3) Override the cell Paint() to use a WebClient to get the image and use e.Graphics.DrawImage(ImageObtainedFromWebClient) to paint the image to the cell. You could use e.Graphics.DrawString((CronosImageDetails)value.DisplayText,...) to overlay the text in the cell.

This quick solution would get you a scrolling imagelist that only loads images as the user scrolls through the list and provides a solid base for improvement.

Recommended further optimizations:

A) Create a backbuffer bitmap and graphics for drawing cell data.

B) Setup Paint() to simply paint the backbuffer instead of doing the work to get the image

C) Create a new cell method LoadImage() that spawns a new thread that downloads the image and paints it onto the back buffer.

D) Have Paint() (or a seperate helper thread) track the direction and acceleration of scrolling and estimate which cells need to be preloaded. Trigger LoadImage() on those cells.

E) Initialize the back buffer of each cell with a loading image.

F) Track and use empirical data from the image loading times to help determine which cells need to be preloaded.

Robert Venables