WPF中动态加载图像
我在使用 WPF 时遇到了一个奇怪的问题,我在运行时从磁盘加载图像并将它们添加到 StackView 容器中。 但是,图像没有显示。 经过一番调试,我发现了窍门,但它确实没有任何意义。 我制作了一个小型演示应用程序来识别问题:
创建一个新的 WPF 项目,然后粘贴代码如下:
xaml:
<Window x:Class="wpfBug.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
<StackPanel Name="sp">
</StackPanel>
</Window>
xaml.cs,粘贴到默认使用下面:
namespace wpfBug
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
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 文件夹并将其命名为“图片” .jpg'
该程序不显示任何内容,除非注释行被取消注释。
谁能解释我做错了什么,或者为什么会发生这种情况? 如果删除图像并运行程序,它将在“int q= ...”行上生成异常。 如果该行被注释,即使不存在图像,程序也会毫无异常地运行。 仅在必要时才加载图像,但是当我将 Image 控件添加到 StackPanel 时,应该加载图像。
有什么想法吗?
编辑:顺便说一句,如果将图像添加为资源,则不需要 'int q = ..' 行。
I have a strange issue with WPF, I was loading images from the disk at runtime and adding them to a StackView container. However, the images were not displayed. After some debugging I found the trick, but it really doesn't make any sense. I've made a small demo app to identify the problem:
Create a new WPF project, and paste code as follows:
xaml:
<Window x:Class="wpfBug.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
<StackPanel Name="sp">
</StackPanel>
</Window>
xaml.cs, paste below default usings:
namespace wpfBug
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
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);
}
}
}
Copy a image to the bin/Debug folder and call it 'picture.jpg'
This program doesn't display anything, unless the commented line is uncommented.
Can anyone explain what I'm doing wrong, or why this happens? If you remove the image and run the program it generates an exception on the 'int q= ...' line. If that line is commented the program runs without exceptions even if no image is present. Loading an image only if nessesary makes sense, but then the image should be loaded when I add the Image control to the StackPanel.
Any ides ?
Edit: By the way, if you add the image as a resource, the 'int q = ..' line is not needed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是因为创造被延迟了。
如果你希望图片立即加载,只需将这段代码添加到init阶段即可。
src.CacheOption = BitmapCacheOption.OnLoad;
像这样:
It is because the Creation was delayed.
If you want the picture to be loaded immediately, you can simply add this code into the init phase.
src.CacheOption = BitmapCacheOption.OnLoad;
like this:
在执行程序集中加载资源的代码中,其中我的图像“Freq.png”位于“图标”文件夹中并定义为“资源”。
如果有人愿意的话,我还做了一个功能...
用法:
In code to load resource in the executing assembly where my image 'Freq.png' was in the folder "Icons" and defined as "Resource".
I also made a function if anybody would like it...
Usage:
这是奇怪的行为,虽然我无法说出为什么会发生这种情况,但我可以推荐一些选项。
首先,观察。 如果您将图像作为内容包含在 VS 中并将其复制到输出目录,则您的代码可以正常工作。 如果图像在VS中被标记为None并且你将其复制过来,则它不起作用。
解决方案 1:FileStream
BitmapImage 对象接受 UriSource 或 StreamSource 作为参数。 让我们改用 StreamSource。
问题:流保持打开状态。 如果在此方法结束时关闭它,则图像将不会显示。 这意味着该文件在系统上保持写锁定状态。
解决方案 2:MemoryStream
这基本上是解决方案 1,但您将文件读入内存流并将该内存流作为参数传递。
现在您可以修改系统上的文件(如果您需要的话)。
This is strange behavior and although I am unable to say why this is occurring, I can recommend some options.
First, an observation. If you include the image as Content in VS and copy it to the output directory, your code works. If the image is marked as None in VS and you copy it over, it doesn't work.
Solution 1: FileStream
The BitmapImage object accepts a UriSource or StreamSource as a parameter. Let's use StreamSource instead.
The problem: stream stays open. If you close it at the end of this method, the image will not show up. This means that the file stays write-locked on the system.
Solution 2: MemoryStream
This is basically solution 1 but you read the file into a memory stream and pass that memory stream as the argument.
Now you are able to modify the file on the system, if that is something you require.
您可以尝试将处理程序附加到 BitmapImage 的各种事件:
解码失败
下载失败
DownloadCompleted
他们可能会告诉您一些有关图像的信息。
You could try attaching handlers to various events of BitmapImage:
DecodeFailed
DownloadFailed
DownloadCompleted
They might tell you a little about what's going on, as far as the image is concerned.
下面是从 URI 加载图像的扩展方法:
使用示例:
就这么简单!
Here is the extension method to load an image from URI:
Sample of use:
Simple as that!