【问题标题】:CollectionView using Observable Collection is not updating images使用 Observable Collection 的 CollectionView 不更新图像
【发布时间】:2022-01-27 18:31:39
【问题描述】:

可观察的集合没有更新,我也在使用集合视图创建类似于 Instagram 的网格布局,当我添加图像时我希望 UI 更新


if(photo.Success)
{
   Photos.Add(new Photo { PhotoPath = photo.PhotoPath});

   OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs(nameof(Photos)));
}

              <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout>
                            <ffimageloading:CachedImage
                                Source="{Binding PhotoPath, Converter={StaticResource Key=path}}"
                                Aspect="AspectFill"
                                HeightRequest="130">
                                <ffimageloading:CachedImage.GestureRecognizers>
                                    <TapGestureRecognizer
                                        CommandParameter="{Binding .}"
                                        Command="{Binding Source={x:Reference dash}, Path=BindingContext.SelectedCommand}"/>
                                </ffimageloading:CachedImage.GestureRecognizers>
                                </ffimageloading:CachedImage>
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
 public class PhotoPathConverter:IValueConverter
    {
        private string pathUrl = "https://photobucket-resized.s3.af-south-1.amazonaws.com/";

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string path = string.Empty;

            if(value != null)
            {
               path = pathUrl + (string)value; 
            }
            return path;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

App.xaml

<converters:PhotoPathConverter x:Key="path"/>

public ObservableCollection<Photo> Photos { get; set; }

有趣的是,当我设置断点时,它会稍微延迟一下

可观察的集合没有更新,我也在使用集合视图创建类似于 Instagram 的网格布局,当我添加图像时我希望 UI 更新

【问题讨论】:

  • Converter={StaticResource Key=path} 看起来不对。这并没有说明要使用哪个转换器。
  • 命名有点奇怪,但这是我在 App 类样式中设置的关键“路径”。转换器确实被调用,但它没有更新
  • 好的。为了让我了解正在发生的事情,请添加使关键“路径”指向该转换器的代码或 xaml。 (它可能不相关,但查看所涉及的整个代码有助于我确定我没有忽略某些东西。)
  • 另外,添加Photos的声明。
  • @ToolmakerSteve 好的,我添加了,Photos = new ObservableCollection();在我的构造函数中。我还注意到,当我添加一个断点时,它会稍微延迟它的工作,它会更新 UI

标签: c# xamarin.forms xamarin.ios


【解决方案1】:

注意:OnPropertyChanged 仅在您设置属性时才重要。当ObservableCollection 更改时,触发的事件是CollectionChanged。这是自动为您完成的。


首先,要让 XAML 看到集合中的更改,它必须是 ObservableCollection,而不是 List

其次,照片必须是一个属性(get/set),而不是一个字段。

声明应如下所示:

public ObservableCollection<MyModel> Photos { get; } = new ObservableCollection<MyModel>();

(或者,您可以在构造函数中使用Photos = new ...。)

或者如果您稍后将“设置”照片,如下所示:

public ObservableCollection<MyModel> Photos {
    get => _photos;
    set {
        _photos = value;
        OnPropertyChanged();
    }
}
private ObservableCollection<MyModel> _photos;

如果这不是问题,那么看看这是否更好。变化:

if (photo.Success)
{
   Photos.Add(new Photo { PhotoPath = photo.PhotoPath});

   OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs(nameof(Photos)));
}

Device.BeginInvokeOnMainThread(() => {
    if (photo.Success)
    {
       Photos.Add(new Photo { PhotoPath = photo.PhotoPath});

       //OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs(nameof(Photos)));
    }
});

说明:有时对 UI 绑定值的更改不会按预期工作,因为 Xamarin(或本机平台操作系统)在内部位于代码中表现不佳的位置。

使用 BeginInvoke queues 包装要在 Xamarin 完成当前操作后在 MainThread(UI 线程)上运行的代码。 (Xamarin 从您拥有该代码的事件处理程序或命令返回。)

我还没有确定在什么条件下这是必要的。 (这样的代码已经“在 MainThread 上”,所以不是因为“在错误的线程上”。)


在更极端的情况下,增加一点延迟会有所帮助:

Device.BeginInvokeOnMainThread(async () => {
    if (photo.Success)
    {
        await System.Threading.Tasks.Task.Delay(200);
        Photos.Add(new Photo { PhotoPath = photo.PhotoPath});
    }
});

【讨论】:

  • 我想我知道问题出在哪里。因为我有一个不同的 AWS 缩略图存储桶,所以我相信当我没有延迟地上传图像时,它会在通过我正在使用的 lambda 函数传输到缩略图存储桶之前被调用。我想我将只使用原始存储桶,因为它可以正常工作。非常感谢您的帮助@ToolmakerSteve
【解决方案2】:

我找到了一种使用 UriImageSource 解决此问题的方法

PhotoPath = new UriImageSource
{
  Uri = new Uri(_http_resized + Object.PhotoPath),
  CachingEnabled = true,
  CacheValidity = TimeSpan.FromDays(2)
};

因为我希望缓存我的图像,如果您希望用户更新它,这会有点困难。我创建了另一个没有缓存的 UriImageSource 实例,然后在更新后设置缓存

PhotoPath = new UriImageSource
{
  Uri = new Uri(_http_resized + Object.PhotoPath),
  CachingEnabled = false,
  CacheValidity = TimeSpan.FromDays(0)
};

Some code.....

PhotoPath.CachingEnabled = true;
PhotoPath.CacheValidity = TimeSpan.FromDays(2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-09
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    相关资源
    最近更新 更多