我正在尝试在代码中设置WPF图像的源代码.图像作为资源嵌入到项目中.通过查看示例,我提出了以下代码.由于某种原因,它不起作用 - 图像不显示.
通过调试,我可以看到流包含图像数据.那有什么不对?
Assembly asm = Assembly.GetExecutingAssembly(); Stream iconStream = asm.GetManifestResourceStream("SomeImage.png"); PngBitmapDecoder iconDecoder = new PngBitmapDecoder(iconStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); ImageSource iconSource = iconDecoder.Frames[0]; _icon.Source = iconSource;
图标的定义如下:
在遇到与您相同的问题并进行一些阅读后,我发现了解决方案 - 包URI.
我在代码中做了以下事情:
Image finalImage = new Image(); finalImage.Width = 80; ... BitmapImage logo = new BitmapImage(); logo.BeginInit(); logo.UriSource = new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png"); logo.EndInit(); ... finalImage.Source = logo;
或者更短,使用另一个BitmapImage构造函数:
finalImage.Source = new BitmapImage( new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png"));
URI分为几部分:
权威: application:///
路径:编译为引用的程序集的资源文件的名称.路径必须符合以下格式:AssemblyShortName[;Version][;PublicKey];component/Path
AssemblyShortName:引用的程序集的简称.
; Version [可选]:包含资源文件的引用程序集的版本.当加载两个或多个具有相同短名称的引用程序集时,将使用此方法.
; PublicKey [可选]:用于对引用的程序集进行签名的公钥.当加载两个或多个具有相同短名称的引用程序集时,将使用此方法.
; component:指定从本地程序集引用所引用的程序集.
/ Path:相对于引用程序集的项目文件夹的根目录的资源文件的名称,包括其路径.
之后的三个斜线application:
必须用逗号替换:
注意:包URI的权限组件是指向包的嵌入式URI,必须符合RFC 2396.此外,"/"字符必须替换为","字符和保留字符,例如"%"和"?" 必须逃脱.有关详细信息,请参阅OPC.
当然,请确保将图像上的构建操作设置为Resource
.
var uriSource = new Uri(@"/WpfApplication1;component/Images/Untitled.png", UriKind.Relative); foo.Source = new BitmapImage(uriSource);
这将在名为"Images"的文件夹中加载一个名为"Untitled.png"的图像,其"Build Action"在名为"WpfApplication1"的程序集中设置为"Resource".
这是一个较少的代码,可以在一行中完成.
string packUri = "pack://application:,,,/AssemblyName;component/Images/icon.png"; _image.Source = new ImageSourceConverter().ConvertFromString(packUri) as ImageSource;
很容易:
要动态设置菜单项的图像,只需执行以下操作:
MyMenuItem.ImageSource = new BitmapImage(new Uri("Resource/icon.ico",UriKind.Relative));
...而"icon.ico"可以位于任何地方(目前它位于"资源"目录中),并且必须作为资源链接...
您也可以将其减少到一行.这是我用来为我的主窗口设置Icon的代码.它假定.ico文件被标记为内容并被复制到输出目录.
this.Icon = new BitmapImage(new Uri("Icon.ico", UriKind.Relative));
最简单的方法:
var uriSource = new Uri("image path here"); image1.Source = new BitmapImage(uriSource);
你有没有尝试过:
Assembly asm = Assembly.GetExecutingAssembly(); Stream iconStream = asm.GetManifestResourceStream("SomeImage.png"); BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.StreamSource = iconStream; bitmap.EndInit(); _icon.Source = bitmap;
这是我的方式:
internal static class ResourceAccessor { public static Uri Get(string resourcePath) { var uri = string.Format( "pack://application:,,,/{0};component/{1}" , Assembly.GetExecutingAssembly().GetName().Name , resourcePath ); return new Uri(uri); } }
用法:
new BitmapImage(ResourceAccessor.Get("Images/1.png"))
下面是一个动态设置图像路径的示例(图像位于光盘上的某个位置而不是构建为资源):
if (File.Exists(imagePath)) { // Create image element to set as icon on the menu element Image icon = new Image(); BitmapImage bmImage = new BitmapImage(); bmImage.BeginInit(); bmImage.UriSource = new Uri(imagePath, UriKind.Absolute); bmImage.EndInit(); icon.Source = bmImage; icon.MaxWidth = 25; item.Icon = icon; }
首先想到的是,你会认为Icon属性只能包含一个图像.但它实际上可以包含任何东西!当我以编程方式尝试将Image
属性直接设置为带有图像路径的字符串时,我意外地发现了这一点.结果是它没有显示图像,而是显示路径的实际文本!
这导致了不必为图标制作图像的替代方案,而是使用带有符号字体的文本来显示简单的"图标".以下示例使用Wingdings字体,其中包含"floppydisk"符号.这个符号实际上是字符<
,它在XAML中具有特殊含义,因此我们必须使用编码版本<
.这就像一场梦!以下显示了一个floppydisk符号作为菜单项上的图标:
如果您的图像存储在ResourceDictionary中,则只需一行代码即可完成:
MyImage.Source = MyImage.FindResource("MyImageKeyDictionary") as ImageSource;
还有一种更简单的方法.如果图像作为资源加载到XAML中,并且有问题的代码是该XAML内容的代码隐藏:
Uri iconUri = new Uri("pack://application:,,,/ImageNAme.ico", UriKind.RelativeOrAbsolute); NotifyIcon.Icon = BitmapFrame.Create(iconUri);