Сведения о вопросе

Drake

09:48, 17th August, 2020

Теги

.net   wpf   data-binding   xaml    

Изображение UriSource и привязка данных

Просмотров: 523   Ответов: 6

Я пытаюсь привязать список пользовательских объектов к изображению WPF, как это:

<Image>
    <Image.Source>
        <BitmapImage UriSource="{Binding Path=ImagePath}" />
    </Image.Source>
</Image>

Но это не работает. Это ошибка, которую я получаю:

"Свойство 'UriSource' или свойство 'StreamSource' должно быть установлено."

Что я упускаю из виду?



  Сведения об ответе

VERSUION

22:00, 4th August, 2020

WPF имеет встроенные преобразователи для определенных типов. Если вы привязываете свойство Source изображения к значению string или Uri , под капотом WPF будет использовать ImageSourceConverter для преобразования значения в ImageSource .

Так

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

будет работать, если свойство ImageSource является строковым представлением допустимого URI для изображения.

Вы можете конечно свернуть свой собственный конвертер Привязок:

public class ImageConverter : IValueConverter
{
    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        return new BitmapImage(new Uri(value.ToString()));
    }

    public object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

и используй его вот так:

<Image Source="{Binding ImageSource, Converter={StaticResource ImageConverter}}"/>


  Сведения об ответе

park

18:54, 6th August, 2020

В этой статье Атула Гупты есть пример кода, который охватывает несколько сценариев:

  1. Обычная привязка изображения к источнику собственность в XAML
  2. Привязка образа ресурса, но из кода позади
  3. Привязка образа ресурса в коде сзади с помощью Application.GetResourceStream
  4. Загрузка изображения из пути к файлу через поток памяти (то же самое применимо при загрузке данных изображения блога из базы данных)
  5. Загрузка изображения из пути к файлу, но с помощью привязки к свойству пути к файлу
  6. Привязка данных изображения к пользовательскому элементу управления, который внутренне имеет управление изображением через свойство зависимостей
  7. То же самое, что и пункт 5, но также гарантирует, что файл не будет заблокирован на жестком диске


  Сведения об ответе

DAAA

08:48, 20th August, 2020

Вы также можете просто установить исходный атрибут, а не использовать дочерние элементы. Для этого ваш класс должен вернуть изображение как Bitmap образ. Вот пример того, как я это сделал

<Image Width="90" Height="90" 
       Source="{Binding Path=ImageSource}"
       Margin="0,0,0,5" />

А свойство класса просто таково

public object ImageSource {
    get {
        BitmapImage image = new BitmapImage();

        try {
            image.BeginInit();
            image.CacheOption = BitmapCacheOption.OnLoad;
            image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
            image.UriSource = new Uri( FullPath, UriKind.Absolute );
            image.EndInit();
        }
        catch{
            return DependencyProperty.UnsetValue;
        }

        return image;
    }
}

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


  Сведения об ответе

Chhiki

01:42, 21st August, 2020

Вам нужно иметь реализацию интерфейса IValueConverter , который преобразует uri в образ. Ваша реализация преобразования IValueConverter будет выглядеть примерно так:

BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(value as string);
image.EndInit();

return image;

Тогда вам нужно будет использовать конвертер в вашей привязке:

<Image>
    <Image.Source>
        <BitmapImage UriSource="{Binding Path=ImagePath, Converter=...}" />
    </Image.Source>
</Image>


  Сведения об ответе

baggs

21:06, 1st October, 2020

Проблема с ответом, который был выбран здесь, заключается в том, что при перемещении вперед и назад конвертер будет срабатывать каждый раз, когда отображается страница.

Это приводит к тому, что новые дескрипторы файлов будут создаваться непрерывно и будут блокировать любые попытки удалить файл, поскольку он все еще используется. Это можно проверить с помощью процесса Explorer.

Если файл изображения может быть удален в какой-то момент, можно использовать такой конвертер, как этот: использование XAML для привязки к System.Drawing.Image в элемент управления System.Windows.Image

Недостатком этого метода потока памяти является то, что изображения загружаются и декодируются каждый раз, и никакое кэширование не может иметь место: "Чтобы предотвратить повторное декодирование изображений, присвойте свойству Image.Source свойство Uri вместо использования потоков памяти" Источник: "Performance tips for Windows Store apps using XAML"

Чтобы решить проблему производительности, шаблон репозитория можно использовать для обеспечения слоя кэширования. Кэширование может происходить в памяти, что может вызвать проблемы с памятью, или в виде файлов миниатюр, которые находятся в папке temp и могут быть очищены при выходе из приложения.


  Сведения об ответе

screen

13:13, 15th August, 2020

вы можете использовать

ImageSourceConverter класс

чтобы получить то, что вы хотите

    img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться