给定的 System.Uri 无法转换为 Windows.Foundation.Uri。

30

我正在尝试在 XAML Metro 应用程序中编程加载一个 BitmapImage。这是我的代码:

var uri = new Uri("/Images/800x600/BackgroundTile.bmp", UriKind.RelativeOrAbsolute);
var imageSource = new BitmapImage(uri);

第二行代码会抛出一个System.ArgumentException异常:

给定的System.Uri无法转换为Windows.Foundation.Uri。请参见http://go.microsoft.com/fwlink/?LinkID=215849获取详细信息。

链接只是指向MSDN主页,没有用处。

我也尝试删除前导的/,以防WinRT对相对URI有不同的期望,但我仍然收到相同的异常。

为什么我对一个看起来完全有效的URI会收到这个异常?


你尝试过实例化 Foundation Uri 吗?这可能吗? - flq
似乎没有Windows.Foundation.Uri类。它有文档记录(http://msdn.microsoft.com/en-us/library/windows/apps/windows.foundation.uri(v=vs.85).aspx),但是当我尝试使用`new Windows.Foundation.Uri()`时,VS2011会在“Uri”下显示红色波浪线,并显示工具提示“名称空间'Windows.Foundation'中不存在类型或命名空间'Uri'(是否缺少程序集引用?)”。这是在我的UI程序集中,所以它应该已经拥有所有重要的引用。 - Joe White
1
@Joe WinRT中确实有这个类,但.NET projection将它隐藏了起来,就像它隐藏了IIterableIVector等。你应该只使用System.Uri - Pavel Minaev
1
@PavelMinaev 我原以为投影应该是用来统一平台的,而不是分裂它们。为什么会有 System.Uri 和 Windows.Foundation.Uri 两个选项,并且在运行时存在损失转换?这只是因为这是开发者预览版吗,还是在正式产品中也会出现这种情况? - Joe White
1
@Joe,这并不是一种有损转换(因为它实际上并没有让你转换它)。将其视为前提条件:任何接受Uri的WinRT方法都期望一个绝对Uri。用.NET术语来说,就好像它写着 if (uri.IsAbsoluteUri) throw new ArgumentException() - 这在.NET中是完全有效的,并且通常是相当合理的。 - Pavel Minaev
显示剩余2条评论
7个回答

34
在消费者预览版中,正确的 URL 格式似乎已更改为 ms-appx:/Images/800x600/BackgroundTile.bmp

你能提供一些文档链接吗?我从“如何引用内容”中看到ms-appx可以在JavaScript中使用,但它是否也适用于基于XAML的UI呢? - Joe White
是的,我可以确认它也适用于基于XAML的用户界面。我没有找到任何关于它的文档 - 只有试错才让我得出这个结果。 - Sander
有人让我“找一个应用程序”来打开URI,而不是导航到资源。 有什么想法吗? this.webBrowser.Navigate(new Uri("ms-appx://Assets/HTML/HelpPage/help.html")); (我也尝试过使用1、2和3个前向斜杠,但都没有成功) - matthewsheets

17

Windows.Foundation.Uri文档来看,WinRT不支持相对URI。我尝试了pack:// URI,但是这导致了UriFormatException异常,所以在WinRT中这似乎也不是正确的方法。

我在这个讨论串上找到了答案:微软专门为WinRT资源发明了另一种URI格式。这个方法可行:

new Uri("ms-resource://MyAssembly/Images/800x600/BackgroundTile.bmp")

请注意,您不需要添加实际的程序集名称 -- MyAssembly 部分是字面文本。


3
您需要使用页面的BaseUri属性或者图片控件的BaseUri属性,如下所示:
//using the page's BaseUri property
BitmapImage bitmapImage = new BitmapImage(this.BaseUri,"/Images/800x600/BackgroundTile.bmp");
image.Source = bitmapImage;

或者

//using the image control's BaseUri property
image.Source = new BitmapImage(image.BaseUri,"/Images/800x600/BackgroundTile.bmp");

您可以在这里查看原因和解决方案。


0

这在 XAML 中可以工作,但在代码中不可行...因此每个控件或页面都有一个 BaseUri 属性,您可以使用它来构建适当的资源 URI...这里是一个示例:

    imageIcon.Source = new BitmapImage(new Uri(this.BaseUri, "Assets/file.gif"));

// 或者使用来自imageIcon的基本URI,同样的效果

    imageIcon.Source = new BitmapImage(new Uri(imageIcon.BaseUri, "Assets/file.gif"));

此外,您需要将构建操作设置为“内容”而不是嵌入式资源...否则您需要使用ms-resource://协议。


0

如果您仍然遇到问题或被要求找到一个应用程序来打开链接,您是否正在尝试使用 WebView?如果是,请尝试使用 ms-appx-web 而不是 ms-appx。

一个例子:

this.webBrowser.Navigate(new Uri("ms-appx-web:///level/level/level/index.html"));

此外要注意,在这些情况下显然不需要URIKind参数。
(我认为你可能需要根据你的引用来变化前导斜杠)

0

我知道这已经有点老了,但我希望这可以帮到你。我用XAML编写了这个程序,并且它对我有效。我使用的IDE是vs-2015和win-10。

<Window>
<Grid>
<Grid.Background>
<ImageBrush ImageSource="NameOfYourImage.JPG or any Image type"/>
</Grid.Background>
<GroupBox x:Name="groupBox" Header="GroupBox" HorizontalAlignment="Left"   Height="248" Margin="58,33,0,0" VerticalAlignment="Top" Width="411">
<GroupBox.Background>
<ImageBrush ImageSource="NameOfYourImage.JPG or any Image type"/>
</GroupBox.Background>
</GroupBox>
</Grid>
</Window>

1
我认为您没有理解问题的要点。当然,它在XAML中起作用。问题不是关于在XAML中引用图像,而是关于在代码中引用图像。 - Joe White

0

MVVM ;)

    public static ImageSource SetImageSource(string uriPath)//.com/image or some path
    {
        // this method very good for mvvm ;)
        try
        {   
            //In Model - public ImageSource AccountPhoto { get; set; } 
            //AccountPhoto = SetImageSource("some path");
            return return new BitmapImage()
            {
                CreateOptions = BitmapCreateOptions.IgnoreImageCache,
                UriSource = new Uri(uriPath)
            };
        }
        catch
        {
            Debug.WriteLine("Bad uri, set default image.");
            return return new BitmapImage()
            {
                CreateOptions = BitmapCreateOptions.IgnoreImageCache,
                UriSource = new Uri("ms-appx:///Avatar/Account Icon.png")
            };
        }
    }

请考虑在您的回答中添加文本。 - Sam Denty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接