为什么我的外部图像不会加载到我的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属性,你只需要添加转换器,它应该工作。