为什么我的外部图像不会加载到我的Silverlight页面中?

问题描述:

为了使这个尽可能简单,我创建了一个新的默认Silverlight 4应用程序,并在生成应用程序时自动创建的测试网站上添加了一个Images文件夹。我放了相同的图像,我们在ClientBin文件夹和Images文件夹中称它为“imageName.png”。现在,一切正常,当我使用XAML这样只需使用图像中的ClientBin:为什么我的外部图像不会加载到我的Silverlight页面中?

<Grid x:Name="LayoutRoot" Background="White"> 
    <StackPanel> 
     <Image Source="imageName.png" Width="16" Height="16"/> 
     <TextBox Text="Hello" /> 
    </StackPanel> 
</Grid> 

但是,当我尝试访问图像的图像文件夹这样的未加载图片:

<Grid x:Name="LayoutRoot" Background="White"> 
    <StackPanel> 
     <Image Source="../Images/imageName.png" Width="16" Height="16"/> 
     <TextBox Text="Hello" /> 
    </StackPanel> 
</Grid> 

我没有得到任何错误,但图像只是不存在。谁能告诉我发生了什么事?我所能找到的一切似乎都表明这应该起作用。

这里的问题是,包含Xap和Xap中的*内容的文件夹被认为是在路径的根目录。因此,路径“/”映射到Xap中的*内容以及Xap所在的文件夹(通常是ClientBin)。任何尝试使用通过被认为是根的父路径将导致Silverlight网络错误。

只能使用绝对Uri访问Xap所在文件夹以外的任何内容。

然后,需要做的是将包含父路径的相对地址转换为绝对地址,然后将其传递给Image.Source属性。优选地,我们希望避免将基本绝对地址硬编码到源代码中。

我们可以使用WebClient对象的BaseAddress属性获取Xap的绝对Url。从中我们可以通过将它与相对地址相结合来组成所需的绝对地址,即使是包含父路径的地址。

值转换器可以在XAML简化这一过程: -

public class WebRelativeConverter : IValueConverter 
{ 
    public Uri Base { get; set; } 

    public WebRelativeConverter() 
    { 
     Base = new Uri((new WebClient()).BaseAddress, UriKind.Absolute); 
    } 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     Uri result = null; 

     if (value is Uri) 
     { 
      result = new Uri(Base, (Uri)value); 
     } 
     else if (value != null) 
     { 
      result = new Uri(Base, value.ToString()); 
     } 
     return result; 
    } 

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

现在在XAML固定值应该是这样的: -

<Grid x:Name="LayoutRoot" Background="White"> 
    <Grid.Resources> 
     <local:WebRelativeConverter x:Key="wrc" /> 
    </Grid.Resources> 
    <StackPanel> 
     <Image DataContext="../Images/imageName.png" Source="{Binding Converter={StaticResource wrc}}" Width="16" Height="16"/> 
     <TextBox Text="Hello" /> 
    </StackPanel> 
</Grid> 

现在,如果你真的是源结合一个对象的Uri或String属性,你只需要添加转换器,它应该工作。