Вопрос

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

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

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

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

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

Это было полезно?

Решение

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}}"/>

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

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

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

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

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

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

Вам необходимо иметь реализацию 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>

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

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

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

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

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

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

Класс ImageSourceConverter

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

    img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top