Xaml — как использовать ImageSource из ViewModel

У меня есть ObservableCollection<Item>, а Item содержит как путь к файлу, так и ImageSource какого-то изображения с диска.

public ObservableCollection<Item> Items { get; set; } = new ObservableCollection<MediaListItem>();
public class Item
{
    public string Image { get; set; } // Full path to the image
    public ImageSource ImageSource { get; set; }
}

Однако я не могу получить доступ ни к одному из двух атрибутов и отобразить изображение через XAML.

<ListView ItemsSource = "{Binding MediaList}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Padding = "10">
                    <Image Source = "{Binding ImageSource}" VerticalOptions = "Fill"></Image>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Теперь я запутался, потому что я могу вывести string Image через XAML через метку, но вообще не могу отобразить изображение из пути.

Вместо этого попробуйте выполнить привязку к строке пути к изображению. Являются ли пути URL-адресами, полными путями к файлам, частичными путями к файлам и т. д.?

Jason 26.05.2019 17:07

По крайней мере, если у вас нет свойства под названием MediaList

Eldho 27.05.2019 14:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
4 321
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Измените тип ImageSource на String

public class Item
{
    public string ImageSource { get; set; }
}

Применение

List<Item> items = new List<Item>();
items.Add(new Item() { ImageSource = "*THE URL OF IMAGE*" });
ListView.ItemsSource = items;

Как вы можете видеть выше, у меня уже была строка (путь к файлу), но она по какой-то причине не работает при использовании Binding Image. Другими словами, меняю ли я его на строку или нет, это одно и то же (как я уже пробовал).

Bowser 26.05.2019 17:35

вы пробовали этот код List<Item> items = new List<Item>(); items.Add(new Item() { ImageSource = "*THE URL OF IMAGE*" }); ListView.ItemsSource = items;

Ahmed Walid 26.05.2019 17:38

вы можете использовать изображение с диска, начав путь с @"File://"

Ahmed Walid 26.05.2019 17:41

Я согласен с ответом Ахмеда. У меня есть свойство строки пути к изображению в vmodel, которое привязывается к изображению в XAML: public string Text { get { return this.text; } установить { this.text = значение; this.OnPropertyChanged (имя (текст)); } }

CloudArch 05.06.2021 14:12
Ответ принят как подходящий

Вы можете использовать ImageSource.FromFile() или ImageSource.FromUri() вот так

В XAML

<Image  Source = "{Binding  ImageSource}"  Aspect = "AspectFit"  ></Image>

В коде

public ObservableCollection<Item> MediaList { get; set; } = new ObservableCollection<Item>()
        {
            new Item
            {
                ImageSource = ImageSource.FromFile("xamarin.png")
            },
            new Item
            {
                ImageSource = ImageSource.FromUri(new Uri("https://i.stack.imgur.com/4mMod.png"))
            }
        };

Результат

Обновлять

В зависимости от Локальные образы Microsoft

Image files can be added to each application project and referenced from Xamarin.Forms shared code...

To use a single image across all apps, the same filename must be used on every platform, and it should be a valid Android resource name (ie. only lowercase letters, numerals, the underscore, and the period are allowed).

Для получения дополнительной информации взгляните на ответ здесь

Теперь, если вы хотите отобразить изображение, не добавляя его на каждую платформу, вы должны использовать Конвертер.

Например:

  1. Create a new folder called ImagesFolder in shared code then add the image to it

  2. In Code, create a new class called ByteArrayToImageSourceConverter like this

    public class ByteArrayToImageSourceConverter : IValueConverter 
    {
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      {   
        byte[] bytes;
        var assembly = GetType().GetTypeInfo().Assembly; // using System.Reflection;
    
        var stream = assembly.GetManifestResourceStream((string)value); // value = "App1.ImagesFolder.ninja.png"
        using (var ms = new MemoryStream()) // using System.IO; 
        {
            stream.CopyToAsync(ms);
            bytes = ms.ToArray();
        }
        return ImageSource.FromStream(() => new MemoryStream(bytes));
      }
      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      {
        return null;
      }
    }
    

    View Model

    public ObservableCollection<Item> MediaList { get; set; } = new ObservableCollection<Item>()
    {
        new Item
        {
           Image  = "App1.ImagesFolder.ninja.png"
        }
    };
    
  3. В XAML

    <ContentPage xmlns = "http://xamarin.com/schemas/2014/forms"
         xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:local = "clr-namespace:App1"
         x:Class = "App1.MainPage">
    
      <ContentPage.Resources>
        <ResourceDictionary>
           <local:ByteArrayToImageSourceConverter  x:Key = "ByteArrayToImageSourceConverter" />
       </ResourceDictionary>
     </ContentPage.Resources>
    
     <ListView ItemsSource = "{Binding MediaList}" >
        <ListView.ItemTemplate>
          <DataTemplate>
            <ViewCell>
               <Image Source = "{Binding Image, Converter = {StaticResource ByteArrayToImageSourceConverter}}" />
            </ViewCell>
          </DataTemplate>
       </ListView.ItemTemplate>
     </ListView>
    
    </ContentPage>
    

Ссылки по теме

ByteArrayToImageSourceConverter

Общие ресурсы

Как загрузить бинарные изображения в Xamarin?

Я полагаю, это не сработает, если изображение случайно находится где-то на диске (например, на рабочем столе), но только если оно находится в подпапке проекта?

Bowser 27.05.2019 01:41

@Bowser, я изменил свой ответ

Anas Alweish 27.05.2019 13:11

Другие вопросы по теме