强制WPF的BitmapImage从其UriSource重新加载

3

我正在尝试构建一个自定义控件,基于Image,它简单地使图像在定时器上重新加载(从相同的URI)。原始图像显示正常,但似乎没有刷新。

以下是自定义控件代码:

public class RefreshImage : Image
{
    protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);
        this.Loaded += RefreshImage_Loaded;
    }

    private void RefreshImage_Loaded(object sender, RoutedEventArgs e)
    {
        var timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Tick += RefreshImage_Tick;
        timer.Start();
    }

    private void RefreshImage_Tick(object sender, System.EventArgs e)
    {
        var bm = (BitmapImage) Source;
        bm.InvalidateProperty(BitmapImage.UriSourceProperty);
    }
 }

我正在这样使用它:

  <custom:RefreshImage>
      <Image.Source>
          <BitmapImage UriCachePolicy="NoCacheNoStore"
                       CreateOptions="IgnoreImageCache" CacheOption="None"
                       UriSource="{Binding Uri}"/>
      </Image.Source>
  </custom:RefreshImage>
InvalidateProperty 的文档似乎表明这正是我所需要的:
``` 您还可以使用 InvalidateProperty 强制重新评估绑定与无法实现推荐的 INotifyPropertyChanged 通知机制的数据源之间的关系。 ```
在 `Uri` 上引发 `INotifiyPropertyChanged.PropertyChanged` 事件也不会触发图像重新加载。

当图像在您的应用程序中打开时,您能否更改(写入)它? - rmojab63
出于好奇,我尝试使用简单的数据绑定在UriSource上进行测试...但它不起作用。请参见这里2006年的线程: https://social.msdn.microsoft.com/Forums/vstudio/en-US/85cffb5c-05a4-4653-a263-183f20ddd2c2/xaml-setting-bitmapimageurisource-from-binding-doesnt-work?forum=wpf 看起来UriSource是一个一旦设置就不能更改的依赖属性。随后的更改似乎没有任何作用。 - Jack Ukleja
这个问题不是重复的。这个问题是关于为什么一旦设置了UriSource就不能更改的原因。 - Jack Ukleja
1个回答

0

看起来BitmapSource通常是不可变的对象。一旦它们完成初始化,任何进一步的属性更改都将被忽略。我怀疑这包括UriSource

在这个MSDN关于创建自定义ImageSources的文章中,经常重复以下阶段:

当初始化完成时,使用ISupportInitialize接口捕获属性的值。进一步更改属性将被忽略。


1
“一旦属性被设置,它们就会被冻结”并不是正确的说法。除非您实际调用Freeze(),否则BitmapImage不会被冻结。事实上,WPF会缓存从URI加载的图像。如果更改Uri视图模型属性的值,绑定将更新BitmapImage的UriSource。 - Clemens
@Clemens “如果您更改Uri视图模型属性的值,绑定将更新BitmapImage的UriSource” <- 不行。请自行尝试。 - Jack Ukleja
我做了。当然,Uri值必须不同,并且属性必须触发PropertyChanged事件。请注意,绑定源属性(Uri)的更改并不意味着目标依赖属性(UriSource)被设置为新的本地值。它最初被设置为绑定一次,以后不会改变。相反,由绑定产生的值会改变。 - Clemens
我已经尝试将绑定的Uri设置为不同的值。正如我所说,它不起作用。我不确定你和我做了什么不同。绑定可能会产生不同的值,但它被BitmapImage忽略或导致它抛出异常。这是一个演示它不起作用的示例项目:https://expirebox.com/download/9da54d9e5e1f8004ba65ba26e0a5b77b.html - Jack Ukleja
不确定我在那里测试了什么。相当确定你在那个示例项目中做了什么。稍后我会检查一下。 - Clemens
你肯定已经知道了,但是你可以将RefreshImage的“Source”属性绑定到“Uri”,而不是在XAML中使用绑定的“UriSource”属性设置BitmapImage。 - Clemens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接