6

What's the best way to pass an image in a WCF service, and after passing it, display it in a WPF datagrid?

1
  • How large on average are the images you are dealing with? How many of them do you need to deal with in a single call? There are several good solutions to your question, but it really depends on the amount of information that you have to deal with on each call. Returning it as a byte array is only a good solution if your images are going to be relatively small and you don't have to return a large number of them at a time (I ask because you are putting it in a datagrid, so I assume you could be getting a number of them back from the service. Commented May 10, 2009 at 14:22

2 Answers 2

8
+50

I'm not saying this is the only or the best solution, but we have it working like this:

What you need to do is:

Create a WCF method that would return the image by some id or whatever. It should return byte array (byte[]):

public byte[] GetImage(int id)
{
  // put your logic of retrieving image on the server side here
}

In your data class (objects displayed in the grid) make a property Image, its getter should call the WCF method and convert byte array to a BitmapImage:

public BitmapImage Image
{
  get
  {
  // here - connection is your wcf connection interface
  //        this.ImageId is id of the image. This parameter can be basically anything
  byte[] imageData = connection.GetImage(this.ImageId);    

  // Load the bitmap from the received byte[] array
  using (System.IO.MemoryStream stream = new System.IO.MemoryStream(imageData, 0, imageData.Length, false, true))
    {
    BitmapImage bmp = new BitmapImage();
    bmp.BeginInit();
    bmp.StreamSource = stream;

    try
      {
      bmp.EndInit();
      bmp.Freeze(); // helps for performance

      return bmp;
      }
    catch (Exception ex)
      {
      // Handle exceptions here
      }

    return null; // return nothing (or some default image) if request fails
    }
  }
}

In your cell template (or wherever) put an Image control and bind its Source property to the Image property created above:

<DataTemplate> <!-- Can be a ControlTemplate as well, depends on where and how you use it -->
  <Image
    Source={Binding Image, IsAsync=true}
    />
</DataTemplate>

The simplest way to not make UI freeze when retrieving the images would be setting IsAsync property to false like I did. But there's a lot to improve. E.g. you could show some loading animation while the Image is being loaded.

Showing something while loading something else can be accomplished using PriorityBinding (you can read about it here: http://msdn.microsoft.com/en-us/library/ms753174.aspx).

Sign up to request clarification or add additional context in comments.

2 Comments

This is only a good answer if the images are small... depending on the size of the image. If they are large or if there is a high volume of requests this solution will not work.
Good point, Brian. It would be nice (for the common good) if you could share your thoughts on how to deal with lots of large images.
0

Can you load the WPF image from a stream? If so, then you can write the WCF service to return the System.IO.Stream type.

2 Comments

i don't know that's why i ask
You can send a stream as part of a message, as long as the stream is marked to be the only part of the body of the message. All other fields of the message will have to go to the header.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.