Writing...Data Services

Coding and writing about OData and now Windows Azure Mobile Services...

Binding Media Resource Streams to XAML Controls

Binding Media Resource Streams to XAML Controls

  • Comments 1

I came across an interesting problem as I was working on the Windows Phone 7 client code for my next installment of the WCF Data Services blog post series on streaming. In this series, I have been using a property on my PhotoInfo entity named StreamUri to hold the URI of the image used for binding in the client UI. However, because we are dealing with a Media Link Entry (MLE), I was reminded that the correct way to get the URI of the related Media Resource (MR) on the client is by calling the GetReadStreamUri method on the DataServiceContext. This returns the value of the edit-media link for the MLE in the feed, which the service guarantees to be correct. When you rely on some property that has “Uri” in the name, your mileage may vary.

At any rate, I had thought that the obvious way to bind to the true edit-media link URI value was to extend my entity definition (since it’s a partial class) to add a StreamUri property that calls the GetReadStreamUri method in the getter. This works great for read-only binding. However, there is a flaw to doing it this way, which may be a product bug. When you create a new MLE with a binary MR stream, the client first sends a POST to create the MR followed by the MLE, with default values. The client sends second a MERGE request to update the new MLE with client values. The problem is that the client somehow doesn’t know that the StreamUri extension property isn’t part of the entity defined in the data service. Hence, poof! An error in the data service during the MERGE operation “I don’t know what to do with this StreamUri property.” I think that this may only occur in the MLE scenario.

Since my client application (in this case WP7) is XAML-based, value converters to the rescue! Instead, I defined a converter that takes my entity object binding and returns the URI to which to bind, as follows:

public class StreamUriConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        // Return the URI of the media resource stream for binding.
        return App.ViewModel.Context.GetReadStreamUri(value);
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

And here’s what the XAML looks like (I should mention that because the root DataContext of the page is set to my DataServiceCollection<PhotoInfo> binding collection and the Image is in a ListBox control, the default binding is to a PhotoInfo object):


<StackPanel.Resources>
    <converter:StreamUriConverter x:Key="getStreamUri" />
</StackPanel.Resources>
<Image Source="{Binding Converter={StaticResource getStreamUri}}"
        Height="75" Width="50" /> 
 

And, voilà! Binding to the edit-media link URI of the MR in my WP7 app, and you can also add new MLEs in the steaming data service:

image

I’ll let you know when this new Windows Phone 7 post goes up on the WCF Data Services team blog.

Cheers!

Glenn Gailey

***UPDATE***3/21/2011****

I did run into a small snag in implementing this solution. While binding data to a property of an object that implements INotifyPropertyChanged is really nice because property change notifications are sent to the bound control, this solution binds to the actual object and not a property (for the reasons discussed above). The only way that I could figure this out was to reset the binding, which I did by nulling out the DataContext property and then reassigning it to the ViewModel instance.

***UPDATE #2*****3/22/2011****

I found a way to keep an extension property from being sent in MERGE and POST requests mentioned in one of Phani's blog posts. Unfortunately, this involves handling the WritingEntity event and hacking the request to remove the XML that defines the extension property. While this is a good general approach to removing properties from the request (such as in a MERGE reques-- see my other post about this), I think that my converter-based solution without an extension property is easier in this scenario.

Leave a Comment
  • Please add 3 and 3 and type the answer here:
  • Post
  • Instead of having to reset the binding, you can combine your solution with the solution you referenced. i.e. Add an extension property “public Uri StreamUri“, and write a converter to convert Uri to BitmapImage.

    Then your Xaml will look like this:

    <Image Source="{Binding IconImageUri, Converter={StaticResource uriBitmapImageConverter}}" />

Page 1 of 1 (1 items)