我正在将按钮的内容设置为图像。它看起来像这样:
<Button>
<Image Source="pack://application:,,,/NavigationImages/nav_up_left.png" />
</Button>
在我的项目中,我有一个名为NavigationImages的子文件夹,在该文件夹中是图像文件nav_up_left.png.
当我查看设计器图像出现时,但是在运行时,我得到一个IOException错误,说它无法找到资源。
构建操作设置为资源。
实际上,这在一个项目中工作得很好。但是当我把它复制到另一个项目上时,它失败了。这似乎是一个非常简单的问题,但我发现自己被难住了,准备开始拔头发。@_@
您的想法和建议将不胜感激!
我想明白了…
我将xaml代码从一个输出类型为Windows应用程序的项目复制到另一个输出类型为类库的项目。
我当时没有想到这一点,但很明显,当输出类型是Class Library时,包URI需要更改。
所以我把"pack://application:,,,/NavigationImages/nav_up_left.png"
改成了"/ProjectName;component/NavigationImages/nav_up_left.png"
,现在它工作得很好。
我不是100%清楚为什么这是工作,而不是前者。我已经通读了关于WPF中包uri的MSDN文档,但也许我误解了一些东西。
如果有人能给我一个很好的解释,为什么我以前的东西在输出类型为Class Library的项目中不起作用,我将不检查这个答案。
我可能错过了一些非常简单的东西。@_@
我刚刚为同样的问题挣扎了很长一段时间,我认为原始中出现问题的部分原因是缺少"component"这个词。例如,我有
myBitmapImage.UriSource = new Uri(@"pack://application:,,,/MyApp;images/mona2.jpg");
but 应该有
... = new Uri(@"pack://application:,,,/MyApp;component/images/mona2.jpg");
单词"component"不是路径名的一部分,尽管它出现了——它是一个必须存在的字符串字面值。为什么?我猜是有人觉得这是个好主意。
对于那些纠结于其他部分的人来说,"MyApp"怎么样?这是议会的名字。右键单击您的项目名称,选择"Properties…",在"Application"选项卡下,您将看到"程序集名称:"字段。
如果你不想搜索它(或者担心它可能改变,破坏你的代码),你可以这样做:
String appUri = @"pack://application:,,,/" +
System.Reflection.Assembly.GetEntryAssembly().GetName().Name + ";";
String path = appUri + "component/images/mona2.jpg";
myBitmapImage.UriSource = new Uri(path);
不是很漂亮的代码,我承认——它显然可以被缩短——但我希望它能让你到达你需要去的地方。记得将你的镜像文件的"Build"属性设置为"Resource"!
只是为了让大家了解你的情况。第二个包uri。那个有用的。用于位于程序集中而不是主机应用程序中的资源。听起来,主机应用程序正在从有问题的类库加载这个资源?
你可以在这里看到包uri方案的差异:MSDN包URI方案
当从主程序集引用一个资源和从另一个程序集引用一个资源时,uri会有轻微的变化。
同时,pack://application:…包含了所谓的"权限",省略它基本上会使它成为一个相对路径,在假定应用程序权限的大多数情况下,两者都是有效的。
编辑:基本上是因为/子文件夹/Resource.xaml(.jpg等)和/Assembly;component/Resource。Xaml非常相似,后者告诉解析器/加载器它正在查找引用的程序集,而不是主应用程序的程序集。(我想这有助于加快搜索速度)。
另一个正确的解决方案:
一旦你的图像构建动作设置为"资源",你已经重建,导航到你的<Image />
对象的属性。属性窗口将提供一个…文件资源浏览器,因此在选择图像时,<Image />
的Source="..."
属性将被正确填充。