Image UriSource и привязка данных - PullRequest
       64

Image UriSource и привязка данных

60 голосов
/ 21 августа 2008

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

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

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

«Должно быть установлено свойство« UriSource »или свойство« StreamSource »."

Чего мне не хватает?

Ответы [ 6 ]

76 голосов
/ 21 августа 2008

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

So

<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}}"/>
22 голосов
/ 14 мая 2009

Эта статья , написанная Атулом Гуптой, содержит пример кода, охватывающий несколько сценариев:

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

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

<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;
    }
}

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

8 голосов
/ 21 августа 2008

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

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>
7 голосов
/ 15 декабря 2012

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

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

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

Недостаток этого метода потока памяти заключается в том, что изображения загружаются и декодируются каждый раз, и кеширование не может быть выполнено: «Чтобы предотвратить декодирование изображений более одного раза, назначьте свойство Image.Source из Uri вместо использования потоков памяти» Источник: «Советы по производительности для приложений Магазина Windows, использующих XAML»

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

4 голосов
/ 20 октября 2013

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

Класс ImageSourceConverter

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

    img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...