我试图在代码中设置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;
图标的定义如下:<Image x:Name="_icon" Width="16" Height="16" />
下面是一个动态设置映像路径的例子(映像位于磁盘上的某个位置,而不是作为资源构建):
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字体。这个符号实际上是字符<,它在XAML中有特殊的含义,所以我们必须使用编码版本<代替。这就像做梦一样!下面将软盘符号显示为菜单项上的图标:
<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
<MenuItem.Icon>
<Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings"><</Label>
</MenuItem.Icon>
</MenuItem>
在遇到与您相同的问题并进行了一些阅读之后,我发现了解决方案—打包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被分成几个部分:
Authority: application:///
Path: The name of a resource file that is compiled into a referenced assembly. The path must conform to the following format: AssemblyShortName[;Version][;PublicKey];component/Path
AssemblyShortName: the short name for the referenced assembly.
;Version [optional]: the version of the referenced assembly that contains the resource file. This is used when two or more referenced assemblies with the same short name are loaded.
;PublicKey [optional]: the public key that was used to sign the referenced assembly. This is used when two or more referenced assemblies with the same short name are loaded.
;component: specifies that the assembly being referred to is referenced from the local assembly.
/Path: the name of the resource file, including its path, relative to the root of the referenced assembly's project folder.
application:后面的三个斜杠必须用逗号代替:
注意:包URI的授权组件
是一个嵌入式URI,指向
包装,必须符合RFC 2396。
此外,“/”字符必须
替换为“,”字符,
以及保留字符,如“%”
"?"必须转义。查看OPC
获取详细信息。
当然,还要确保将映像上的构建操作设置为Resource。
这是我的方式:
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"))
将框架放在VisualBrush中:
VisualBrush brush = new VisualBrush { TileMode = TileMode.None };
brush.Visual = frame;
brush.AlignmentX = AlignmentX.Center;
brush.AlignmentY = AlignmentY.Center;
brush.Stretch = Stretch.Uniform;
把VisualBrush放在几何绘图中
GeometryDrawing drawing = new GeometryDrawing();
drawing.Brush = brush;
// Brush this in 1, 1 ratio
RectangleGeometry rect = new RectangleGeometry { Rect = new Rect(0, 0, 1, 1) };
drawing.Geometry = rect;
现在将几何绘图放在DrawingImage中:
new DrawingImage(drawing);
把这个放在你的图片源上,然后是voilà!
你可以做得更简单:
<Image>
<Image.Source>
<BitmapImage UriSource="/yourassembly;component/YourImage.PNG"></BitmapImage>
</Image.Source>
</Image>
在代码中:
BitmapImage image = new BitmapImage { UriSource="/yourassembly;component/YourImage.PNG" };