This came via Mike who was playing with some Silverlight sample but I thought it was worth sharing.
Say I’ve got this really simple piece of UI in Silverlight;
<UserControl x:Class="SilverlightApplication2.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SilverlightApplication2" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.Resources> <local:DataClass x:Key="dataContext"/> </Grid.Resources> <Image Source="{Binding MyUri}" DataContext="{StaticResource dataContext}"/> </Grid> </UserControl>
and I’ve got this code that lives behind it;
namespace SilverlightApplication2 { public class DataClass { public Uri MyUri { get { return (new Uri("Images/img1.jpg", UriKind.Relative)); } } } public partial class Page : UserControl { public Page() { InitializeComponent(); } } }
All looks fine – we have our Source on our image bound to a property called MyUri on an instance of the type DataClass and that instance is created declaratively from XAML.
However, it doesn’t work and I think it’s because we are binding a property of type ImageSource ( the Source property on Image ) to a property of type Uri and there’s no natural converter. This is initially a bit odd because if we change the type of our property MyUri to be a string then that’ll just naturally work. So, we need a converter. The hackiest one we could implement might look like;
public class UriToImageSourceConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { // No checks... return (new BitmapImage((Uri)value)); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }
and then I can tweak my XAML to be something like;
<UserControl x:Class="SilverlightApplication2.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SilverlightApplication2" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.Resources> <local:DataClass x:Key="dataContext"/> <local:UriToImageSourceConverter x:Key="uriToImageConverter" /> </Grid.Resources> <Image Source="{Binding MyUri,Converter={StaticResource uriToImageConverter}}" DataContext="{StaticResource dataContext}"/> </Grid> </UserControl>
and we’re back in business.