【发布时间】:2010-09-25 17:53:59
【问题描述】:
对于需要 10 到 20 个小图标和图像用于说明目的的 WPF 应用程序,将这些作为嵌入式资源存储在程序集中是正确的方法吗?
如果是这样,我如何在 XAML 中指定 Image 控件应从嵌入式资源加载图像?
【问题讨论】:
标签: c# .net wpf embedded-resource
对于需要 10 到 20 个小图标和图像用于说明目的的 WPF 应用程序,将这些作为嵌入式资源存储在程序集中是正确的方法吗?
如果是这样,我如何在 XAML 中指定 Image 控件应从嵌入式资源加载图像?
【问题讨论】:
标签: c# .net wpf embedded-resource
是的,这是正确的方法。您可以使用路径在资源文件中使用图像:
<StackPanel Orientation="Horizontal">
<CheckBox Content="{Binding Nname}" IsChecked="{Binding IsChecked}"/>
<Image Source="E:\SWorking\SharePointSecurityApps\SharePointSecurityApps\SharePointSecurityApps.WPF\Images\sitepermission.png"/>
<TextBlock Text="{Binding Path=Title}"></TextBlock>
</StackPanel>
【讨论】:
以下工作并且要设置的图像是属性中的资源:
var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(MyProject.Properties.Resources.myImage.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
MyButton.Background = new ImageBrush(bitmapSource);
img_username.Source = bitmapSource;
【讨论】:
在执行程序集中加载资源的代码中,我的图像 Freq.png 位于文件夹 Icons 中并定义为 Resource:
this.Icon = new BitmapImage(new Uri(@"pack://application:,,,/"
+ Assembly.GetExecutingAssembly().GetName().Name
+ ";component/"
+ "Icons/Freq.png", UriKind.Absolute));
我也做了一个函数:
/// <summary>
/// Load a resource WPF-BitmapImage (png, bmp, ...) from embedded resource defined as 'Resource' not as 'Embedded resource'.
/// </summary>
/// <param name="pathInApplication">Path without starting slash</param>
/// <param name="assembly">Usually 'Assembly.GetExecutingAssembly()'. If not mentionned, I will use the calling assembly</param>
/// <returns></returns>
public static BitmapImage LoadBitmapFromResource(string pathInApplication, Assembly assembly = null)
{
if (assembly == null)
{
assembly = Assembly.GetCallingAssembly();
}
if (pathInApplication[0] == '/')
{
pathInApplication = pathInApplication.Substring(1);
}
return new BitmapImage(new Uri(@"pack://application:,,,/" + assembly.GetName().Name + ";component/" + pathInApplication, UriKind.Absolute));
}
用法(假设您将函数放在 ResourceHelper 类中):
this.Icon = ResourceHelper.LoadBitmapFromResource("Icons/Freq.png");
注意:见MSDN Pack URIs in WPF:pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml
【讨论】:
new Uri(@"pack://application:,,,/" + pathInApplication) 也可以解决问题。
如何使用资源的完整说明:WPF Application Resource, Content, and Data Files
以及如何引用它们,请阅读“Pack URIs in WPF”。
简而言之,甚至可以通过引用/引用程序集引用资源。
【讨论】:
我发现使用图像、视频等的最佳做法是:
<Image Source="/WPFApplication;component/Images/Start.png" />
好处:
【讨论】:
如果您使用的是Blend,为了使其更加简单并且在获取 Source 属性的正确路径时不会遇到任何问题,只需将图像从“项目”面板拖放到设计师。
【讨论】:
是的,这是正确的方法。
您可以使用资源文件中的图像,只需使用路径:
<Image Source="..\Media\Image.png" />
您必须将图像文件的构建操作设置为“资源”。
【讨论】:
如果您将在多个地方使用图像,那么值得将图像数据仅加载一次到内存中,然后在所有Image 元素之间共享。
为此,请在某处创建一个BitmapSource 作为资源:
<BitmapImage x:Key="MyImageSource" UriSource="../Media/Image.png" />
然后,在您的代码中,使用类似:
<Image Source="{StaticResource MyImageSource}" />
就我而言,我发现我必须将Image.png 文件设置为具有Resource 的构建操作,而不仅仅是Content。这会导致图像在您编译的程序集中携带。
【讨论】:
DynamicResource 标记扩展而不是 StaticResource,假设你知道在编译时间。在 WPF 中,您可以在运行时创建资源字典。事实上,当您加载 Xaml 文档时会发生这种情况,只是您没有看到等效的 C#。
Width="{Binding Source.PixelWidth, RelativeSource={RelativeSource Self}}" 添加到Image,否则我经常会看到由于某种原因(例如 16x16 图标被拉伸到看起来像 200x200 像素的东西),图像被奇怪地放大了。跨度>
这对我有用:
<BitmapImage x:Key="MyImageSource" UriSource="Resources/Image.png" />
【讨论】:
有些人询问是否在代码中执行此操作,但没有得到答案。
找了好几个小时找到了一个很简单的方法,没有找到例子,所以在这里分享一下 它适用于图像。 (我的是 .gif)
总结:
它返回 ImageSource“目的地”似乎喜欢的 BitmapFrame。
用途:
doGetImageSourceFromResource ("[YourAssemblyNameHere]", "[YourResourceNameHere]");
方法:
static internal ImageSource doGetImageSourceFromResource(string psAssemblyName, string psResourceName)
{
Uri oUri = new Uri("pack://application:,,,/" +psAssemblyName +";component/" +psResourceName, UriKind.RelativeOrAbsolute);
return BitmapFrame.Create(oUri);
}
学习:
根据我的经验,包字符串不是问题,请检查您的流,特别是如果第一次阅读它已经设置了指针 到文件末尾,您需要将其重新设置为零才能再次读取。
我希望这可以为您节省很多时间,我希望这篇文章对我有用!
【讨论】: