UriSource изображения и привязка данных
Я пытаюсь привязать список пользовательских объектов к изображению WPF следующим образом:
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding Path=ImagePath}" />
</Image.Source>
</Image>
но это не работает. Это ошибка, которую я получаю:
"свойство' UriSource 'или свойство' StreamSource ' должны быть установлены."
чего мне не хватает?
6 ответов:
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}}"/>
в этой статье by Atul Gupta имеет пример кода, который охватывает несколько сценариев:
- привязка образа обычного ресурса к свойству источника в XAML
- привязка изображения ресурса, но из кода за
- привязка изображения ресурса в коде позади с помощью приложения.GetResourceStream
- загрузка изображения из пути к файлу через поток памяти (то же самое применимо при загрузке данных изображения блога из базы данных)
- загрузка изображения из пути к файлу, но с помощью привязки к свойству пути к файлу
- привязка данных изображения к пользовательскому элементу управления, который внутренне имеет управление изображением через свойство зависимостей
- то же самое, что и пункт 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 для привязки к a Система.Рисунок.Изображение в систему.Окна.Управление изображением
недостатком этого метода потока памяти является то, что изображения загружаются и декодируются каждый раз, и никакое кэширование не может иметь место: "Чтобы предотвратить декодирование изображений более одного раза, назначьте изображение.Исходное свойство из Uri вместо использования потоков памяти" Источник: "советы по производительности для приложений Магазина Windows с использованием XAML"
чтобы решить проблему производительности, шаблон репозитория можно использовать для обеспечьте слой кэширования. Кэширование может происходить в памяти, что может вызвать проблемы с памятью, или в виде файлов миниатюр, которые находятся во временной папке, которая может быть очищена при выходе из приложения.
вы можете использовать
ImageSourceConverter class
чтобы получить то, что вы хотите
img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");
Comments