我对WPF有一个奇怪的问题,我在运行时从磁盘加载图像并将它们添加到StackView容器中.但是,图像未显示.经过一些调试我找到了诀窍,但它确实没有任何意义.我制作了一个小型演示应用程序来识别问题:
创建一个新的WPF项目,并粘贴代码如下:
XAML:
xaml.cs,粘贴在默认值下面:
namespace wpfBug { ////// Interaction logic for Window1.xaml /// public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { Image i = new Image(); BitmapImage src = new BitmapImage(); src.BeginInit(); src.UriSource = new Uri("picture.jpg", UriKind.Relative); src.EndInit(); i.Source = src; i.Stretch = Stretch.Uniform; //int q = src.PixelHeight; // Image loads here sp.Children.Add(i); } } }
将图像复制到bin/Debug文件夹并将其命名为"picture.jpg"
除非注释行被取消注释,否则此程序不显示任何内容.
任何人都可以解释我做错了什么,或者为什么会这样?如果删除图像并运行程序,它会在'int q = ...'行生成异常.如果该行被注释,即使没有图像存在,程序也会无异常地运行.只有当nesseary有意义时加载图像,但是当我将Image控件添加到StackPanel时,应该加载图像.
任何想法?
编辑:顺便说一句,如果您将图像添加为资源,则不需要'int q = ..'行.
这是因为创造被推迟了.如果您希望立即加载图片,只需将此代码添加到init阶段即可.
src.CacheOption = BitmapCacheOption.OnLoad;
像这样:
src.BeginInit(); src.UriSource = new Uri("picture.jpg", UriKind.Relative); src.CacheOption = BitmapCacheOption.OnLoad; src.EndInit();
在代码中加载执行程序集中的资源,其中我的图像'Freq.png'位于文件夹"Icons"中并定义为"Resource".
this.Icon = new BitmapImage(new Uri(@"pack://application:,,,/" + Assembly.GetExecutingAssembly().GetName().Name + ";component/" + "Icons/Freq.png", UriKind.Absolute));
如果有人愿意,我也做了一个功能......
////// Load a resource WPF-BitmapImage (png, bmp, ...) from embedded resource defined as 'Resource' not as 'Embedded resource'. /// /// Path without starting slash /// Usually 'Assembly.GetExecutingAssembly()'. If not mentionned, I will use the calling assembly ///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)); }
用法:
this.Icon = ResourceHelper.LoadBitmapFromResource("Icons/Freq.png");
这是一种奇怪的行为,虽然我无法说明为什么会这样,但我可以推荐一些选项.
首先,观察.如果将图像作为内容包含在VS中并将其复制到输出目录,则代码可以正常工作.如果图像在VS中标记为"无"并将其复制,则不起作用.
解决方案1:FileStream
BitmapImage对象接受UriSource或StreamSource作为参数.我们改用StreamSource.
FileStream stream = new FileStream("picture.png", FileMode.Open, FileAccess.Read); Image i = new Image(); BitmapImage src = new BitmapImage(); src.BeginInit(); src.StreamSource = stream; src.EndInit(); i.Source = src; i.Stretch = Stretch.Uniform; panel.Children.Add(i);
问题:流保持打开状态.如果在此方法结束时关闭它,图像将不会显示.这意味着该文件在系统上保持写锁定状态.
解决方案2:MemoryStream
这基本上是解决方案1,但是您将文件读入内存流并将该内存流作为参数传递.
MemoryStream ms = new MemoryStream(); FileStream stream = new FileStream("picture.png", FileMode.Open, FileAccess.Read); ms.SetLength(stream.Length); stream.Read(ms.GetBuffer(), 0, (int)stream.Length); ms.Flush(); stream.Close(); Image i = new Image(); BitmapImage src = new BitmapImage(); src.BeginInit(); src.StreamSource = ms; src.EndInit(); i.Source = src; i.Stretch = Stretch.Uniform; panel.Children.Add(i);
现在,您可以修改系统上的文件,如果这是您需要的.