显示默认图像并在实际图像加载完成后更改它
我有一个 WPF 标记扩展,负责按名称检索图像,返回一个 BitmapImage 对象。
<Image Source="{my:ImageProvider ImageName=myImageName}"></Image>
由于检索图像是一项可能需要几秒钟的操作,因此我想显示默认图像并在准备好后显示请求的图像。
我尝试做的是这样的事情,但是由于这可能会更改 BitmapImage 对象,因此它不会更新 UI(示例代码):
BitmapImage img;
public override object ProvideValue(IServiceProvider serviceProvider)
{
img = new BitmapImage(new Uri(@"D:\defaultImage.png", UriKind.Absolute));
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
return img;
}
void bw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
System.Threading.Thread.Sleep(5000);
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
img.UriSource = new Uri(@"D:\actualImage.png", UriKind.Absolute);
}
有没有办法可以更新 UI 以使用修改了 BitmapImage
(类似于 INotifyPropertyChanged)或者是否有不同的方法来实现此目的?
I have a WPF markup extension in charge of retrieving images by name, returning a BitmapImage
object.
<Image Source="{my:ImageProvider ImageName=myImageName}"></Image>
Since retrieving an image is an operation that can possibly take a few seconds, I'd like to show a default image and display the requested image once it's ready.
What I tried to do is something like this, but as this may change the BitmapImage
object, it won't update the UI (sample code):
BitmapImage img;
public override object ProvideValue(IServiceProvider serviceProvider)
{
img = new BitmapImage(new Uri(@"D:\defaultImage.png", UriKind.Absolute));
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
return img;
}
void bw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
System.Threading.Thread.Sleep(5000);
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
img.UriSource = new Uri(@"D:\actualImage.png", UriKind.Absolute);
}
Is there a way I can update the UI to use the modified BitmapImage
(something like INotifyPropertyChanged) or is there a different approach to achieve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我猜
PriorityBinding
是您可能正在寻找的。您可以绑定到两个不同的 DP,将实际图像源作为最高绑定,并且不要忘记将该绑定的
IsAsync
属性设置为 true。一旦您的图像源准备就绪,它将自动替换第二个绑定。
请参阅此链接开始 - http://msdn .microsoft.com/en-us/library/system.windows.data.prioritybinding.aspx
PriorityBinding
is what you might be looking for i guess.You can bind to two different DP's with your actual image source as the highest binding and not forgot to set
IsAsync
property to true for that binding.Once, your image source is ready it will automatically replaced the second binding.
Refer to this link to get started - http://msdn.microsoft.com/en-us/library/system.windows.data.prioritybinding.aspx
我最终有两种方法可以做到这一点。两种方法都使用包装图像并实现
INotifyPropertyChanged
的类:第一种方法
一旦有了这个,我就可以让我的标记扩展返回一个
ImageSourceWrapper
对象并绑定到它,就像所以我不太喜欢这种方式,因为它非常混乱,并且必须了解 ImageSourceWrapper 类,而不是简单地使用 ImageSource。然后我想出了第二种方法。
第二种方法
在这种方法中,我仍然使用
ImageSourceWrapper
类,但不是让我的标记扩展返回ImageSourceWrapper
对象,而是返回一个我设置为绑定的绑定对象到ImageSourceWrapper
对象。标记扩展看起来像这样:
然后我可以在 XAML 中使用它,如下所示
这种方式首先显示默认图像,一旦检索到请求的图像,就会显示它。
抱歉,如果这里的代码不完全正确,我现在还没有接近代码。希望目前这足以表达主要思想。
I ended up with two ways to do this. Both ways use a class that wraps the image and implements
INotifyPropertyChanged
:First Approach
Once I have this, I can have my markup extension return an
ImageSourceWrapper
object and bind to it, like soI didn't really like this way, since it's pretty messy and involves having to know the
ImageSourceWrapper
class rather than working simply withImageSource
. Then I came up with the second approach.Second Approach
In this approach I still use the
ImageSourceWrapper
class, but instead of having my markup extension return anImageSourceWrapper
object, I return a binding object which I set up to be bound to anImageSourceWrapper
object.The markup extension looks something like this:
Then I can use it in XAML like this
This way the default image is displayed first, and once the requested image is retrieved, it will be displayed instead.
Sorry if the code here isn't entirely correct, I'm not near the code at the moment. Hopefully this is enough at the moment to express the main idea.