在 GridView 中重新加载绑定图像

Reload bound images in GridView

我有一个 ListView 包含一个 GridView 和一个 ObservableCollection 作为它的 ItemsSource。一列显示来自包含路径的绑定 属性 的图像。有多个条目具有相同的图像路径。现在我正在尝试替换一个图像文件并重新加载所有相关条目的显示图像。

这是我的单元格模板到目前为止的样子(需要 CacheOption 以便在替换时不使用图像文件):

<GridViewColumn.CellTemplate>
  <DataTemplate>
    <Image RenderOptions.BitmapScalingMode="HighQuality">
      <Image.Source>
        <BitmapImage UriSource="{Binding Image}" CacheOption="OnLoad" />
      </Image.Source>
    </Image>
  </DataTemplate>
</GridViewColumn.CellTemplate>

重新加载图像的通常方法似乎是用 BitmapCreateOptions.IgnoreImageCache 创建一个新的 BitmapImage 并将其分配给相应的 Image.Source,替换旧的 BitmapImage

显然,对于数百个 ListView 条目手动执行此操作并不实用。我想我可以刷新 ItemsSource 属性 如果我在我的单元格模板中使用 CreateOptions="IgnoreImageCache" 作为 BitmapImage,但我不确定副作用(例如绕过缓存多次使用同一张图片时)。

重新加载这些图像的正确方法是什么?

我已经在另一个问题中发布了这个,但不知道 link 它是否更好,而且其他人可能会有更好的主意。顺便说一句,我绑定了图片路径。


这是我在我的项目中最终得到的结果(我不得不说我花了很长时间来测试似乎几乎可以工作的不同东西)。你可以看到注释代码也没有工作 100% 不记得为什么)

所以我所有来自应用程序资产的图像都以 "ms-appx:" 开头,我使用设置源而不加载到流,因为这些永远不会改变(默认图像等)

用户创建或更改的其他图像我必须重新加载并使用读取的文件结果设置源(否则当它们被更改时有时它们不会更新)

所以基本上我在几乎所有我使用可以更改的图像(不更改名称)的地方都使用这个转换器。

定义转换器:

<converters:ImageConverter x:Key="ImageConverter" /> 

然后像这样使用

<Image Source="{Binding PictureFilename, Converter={StaticResource ImageConverter}}"
       HorizontalAlignment="Center"
       VerticalAlignment="Center"/>

(另一种解决方法是用不同的方式命名您的图像,然后当您更新源路径时它工作正常。)

public class ImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        try
        {
            var CapturedImage = new BitmapImage();
            CapturedImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
            if (((string)value).StartsWith("ms-appx:"))
            {
                CapturedImage.UriSource = new Uri((string)value, UriKind.RelativeOrAbsolute);
                return CapturedImage;

            }
            var file = (StorageFile.GetFileFromPathAsync(new Uri((string)value, UriKind.RelativeOrAbsolute).LocalPath).AsTask().Result);
            using (IRandomAccessStream fileStream = file.OpenAsync(FileAccessMode.Read).AsTask().Result)
            {
                CapturedImage.SetSource(fileStream);
                return CapturedImage;

            }
        }
        catch (Exception e)
        {
            Logger.Error("Exception in the image converter!", e);
            return new BitmapImage();
        }

        //BitmapImage img = null;
        //if (value is string)
        //{
        //    img = new BitmapImage();
        //    img.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
        //    img.UriSource = new Uri((string)value, UriKind.RelativeOrAbsolute);
        //}

        //if (value is Uri)
        //{
        //    img = new BitmapImage();
        //    img.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
        //    img = new BitmapImage((Uri)value);
        //}

        //return img;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}