Указанное приведение не является действительным при обновлении Item в ObservableCollection, привязанном к Listview - PullRequest
0 голосов
/ 13 октября 2018

Я пытаюсь добавить изображение с устройства в свое приложение в Xamarin, используя https://github.com/jamesmontemagno/MediaPlugin. Странно то, что добавление элемента вызывает исключение в некоторый момент «между строк».Я не знаю, как отладить это и предположить, что это происходит, реализуя OnPropertyChanged неправильно.

Я завернул исключение в блок Try / Catch и, к своему удивлению, узнал, что Предмет действительно добавлен, а App.api.message.MediaFiles.Count() увеличен.Это заставляет меня предположить, что Исключение действительно радует после, но не в .Add(Item).

Это должно быть либо OnPropertyChanged() (Но тогда почему Отладчик не показывает мне эту часть кода?) Или магия за кулисами, когда Xamarin связывает Listview с ...Thumbnail.

Однако, поскольку оба эти варианта относительно новы для меня, здесь вполне вероятна ошибка или неправильное толкование, и любой намек на то, как или где это исследовать, будет принят.

Вот что я делаю вдеталь:

 [...]
    public MainPage()
    {
        InitializeComponent();
        BindingContext = App.api.message;
        Media.ItemsSource = App.api.message.MediaFiles;
      [...]
    }

Listview в XAML:

[...]
<ListView x:Name="Media" BackgroundColor="#f1f1f1" HasUnevenRows="true" IsVisible="true" Header="Media" ItemTapped="RemoveImage" RowHeight="90" HeightRequest="120">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding thumbnail}" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView> 
[...]

С file с выбора или получения изображения, которое я делаю:

    public void AddFile(MediaFile file)
    { 
        Classes.MessageClass.Media Item = new Classes.MessageClass.Media();

        Item.Filename = file.Path;

        Item.Thumbnail = ImageSource.FromStream(() =>
        {
            var stream = file.GetStreamWithImageRotatedForExternalStorage();
            return stream;
        });

        file.Dispose();

        FileInfo fileInfo = new FileInfo(Item.Filename);
        Item.Size = fileInfo.Length;

        Console.WriteLine("\n\nOriginal File:{0} \n{1:###,###,###} Bytes\nCaption: {2}\nContent Type: {3}", Item.Filename, Item.Size, Item.Caption,Item.ContentType);

        try
        {
            App.api.message.MediaFiles.Add(Item);  //EXEPTION "Specified cast not Valid"
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exeption: " + ex.Message + " " + ex.Data.Values.ToString());
        }
        Console.WriteLine("Attached Images: " + App.api.message.MediaFiles.Count());
        App.api.message.HasMedia = true;

        UpdateImagesUI();
    }

И наконецмое определение Classes.MessageClass.Media.(Я добавил значения, чтобы избежать проблем с нулевым значением):

public class Media
    {
        public string Caption { get; set; } = "";
        public string Filename { get; set; } = "";
        ImageSource thumbnail;
        public long Size { get; set; } = 0;
        public string ContentType { get; set; } = "";
        public bool IsVideo { get; set; } = false;
        public ImageSource Thumbnail
        {
            get
            { 
                return thumbnail;
            }
            set 
            { 
                if ((thumbnail != value) && (value != null))
                {
                    thumbnail = value;
                    Console.WriteLine("Image Updated");
                    OnPropertyChanged("Thumbnail");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            var changed = PropertyChanged;
            if (changed != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

И in MessageClass(): MediaFiles = new ObservableCollection<Media>();

Наконец, стек:

 (System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x0000f] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.0.0.15/src/Xamarin.iOS/mcs/class/referencesource/System/compmod/system/collections/objectmodel/observablecollection.cs:288 
 at  System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedAction action, System.Object item, System.Int32 index) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.0.0.15/src/Xamarin.iOS/mcs/class/referencesource/System/compmod/system/collections/objectmodel/observablecollection.cs:351 
 at System.Collections.ObjectModel.ObservableCollection`1[T].InsertItem (System.Int32 index, T item) [0x00024] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.0.0.15/src/Xamarin.iOS/mcs/class/referencesource/System/compmod/system/collections/objectmodel/observablecollection.cs:219 
 at System.Collections.ObjectModel.Collection`1[T].Add (T item) [0x00020] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.0.0.15/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/collections/objectmodel/collection.cs:67 
 at SegelnBlogsEditor.MainPage.AddFile (Plugin.Media.Abstractions.MediaFile file) [0x0009e] in /Users/hinnerkweiler/wwwroot/SegelnBlogsEditor/SegelnBlogsEditor/MainPage.xaml.cs:292

1 Ответ

0 голосов
/ 15 октября 2018

ImageSource.FromStream метод принимает Action в качестве параметра, который оценивается каждый раз, когда ViewCell необходимо визуализировать.Использование ссылки file внутри действия для последующего использования и удаление его приведет к исключениям.

Редактировать:

Лучшим подходом будет получение изображения из имени файла

Image.Thumbnail = ImageSource.FromFile(Item.Filename);
...