Xaml - 如何从 ViewModel 使用 ImageSource [英] Xaml - how to use ImageSource from ViewModel
问题描述
我有一个 ObservableCollection
和一个 Item
包含一个文件路径和一个来自磁盘的一些图像的 ImageSource
.
public ObservableCollection- 项目{得到;放;} = new ObservableCollection
();
公共类项目{公共字符串图像 { 获取;放;}//图像的完整路径公共 ImageSource ImageSource { 获取;放;}}
但是,我无法访问这两个属性中的任何一个并通过 XAML 显示图像.
<ListView.ItemTemplate><数据模板><ViewCell><StackLayout Padding="10"><Image Source="{Binding ImageSource}" VerticalOptions="Fill"></Image></StackLayout></ViewCell></数据模板></ListView.ItemTemplate></ListView>
现在我很困惑,因为我可以通过标签通过XAML输出string Image
,但根本无法显示路径中的图像.
你可以像这样使用 ImageSource.FromFile()
或 ImageSource.FromUri()
在 Xaml 中
在代码中
public ObservableCollection- 媒体列表{获取;放;} = new ObservableCollection
- (){新物品{ImageSource = ImageSource.FromFile("xamarin.png")},新物品{ImageSource = ImageSource.FromUri(new Uri("https://i.stack.imgur.com/4mMod.png"))}};
结果
更新
取决于
在代码中,像这样创建一个名为ByteArrayToImageSourceConverter
的新类
公共类 ByteArrayToImageSourceConverter : IValueConverter{公共对象转换(对象值,类型目标类型,对象参数,文化信息文化){字节[]字节;var assembly = GetType().GetTypeInfo().Assembly;//使用 System.Reflection;var stream = assembly.GetManifestResourceStream((string)value);//value = "App1.ImagesFolder.ninja.png"using (var ms = new MemoryStream())//使用 System.IO;{stream.CopyToAsync(ms);字节 = ms.ToArray();}返回 ImageSource.FromStream(() => new MemoryStream(bytes));}公共对象 ConvertBack(对象值,类型目标类型,对象参数,CultureInfo 文化){返回空;}}
查看模型
public ObservableCollection- 媒体列表{获取;放;} = new ObservableCollection
- (){新物品{Image = "App1.ImagesFolder.ninja.png"}};
在 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><资源字典><local:ByteArrayToImageSourceConverter x:Key="ByteArrayToImageSourceConverter"/></ResourceDictionary></ContentPage.Resources><ListView ItemsSource="{Binding MediaList}" ><ListView.ItemTemplate><数据模板><ViewCell><Image Source="{Binding Image, Converter={StaticResource ByteArrayToImageSourceConverter}}"/></ViewCell></数据模板></ListView.ItemTemplate></ListView></内容页>
相关链接
ByteArrayToImageSourceConverter
I have an ObservableCollection<Item>
and an Item
contains both a file path and an ImageSource
of some image from the disk.
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; }
}
However, I am unable to access any of the two attributes and display an image via 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>
Now I am confused because I am able to output the string Image
via XAML through a label, but can't display an image from the path at all.
You can use ImageSource.FromFile()
or ImageSource.FromUri()
like this
In Xaml
<Image Source="{Binding ImageSource}" Aspect="AspectFit" ></Image>
In Code
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"))
}
};
The result
Update
Depending on Microsoft-Local Images
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).
For more information take a look at the answer here
Now if you want to display an image without adding it to each platform, you should use Converter.
For example:
Create a new folder called
ImagesFolder
in shared code then add the image to itIn Code, create a new class called
ByteArrayToImageSourceConverter
like thispublic 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" } };
In 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>
Related Links
ByteArrayToImageSourceConverter
How to load binary images in Xamarin?
这篇关于Xaml - 如何从 ViewModel 使用 ImageSource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!