Xaml - 如何使用 ViewModel 中的 ImageSource
Xaml - how to use ImageSource from ViewModel
我有一个 ObservableCollection<Item>
和一个 Item
包含文件路径和磁盘中某些图像的 ImageSource
。
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; }
}
但是,我无法访问这两个属性中的任何一个,也无法通过 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>
现在我很困惑,因为我可以通过标签通过 XAML 输出 string Image
,但根本无法显示路径中的图像。
将 ImageSource
类型更改为 String
public class Item
{
public string ImageSource { get; set; }
}
用法
List<Item> items = new List<Item>();
items.Add(new Item() { ImageSource = "*THE URL OF IMAGE*" });
ListView.ItemsSource = items;
您可以像这样使用 ImageSource.FromFile()
或 ImageSource.FromUri()
在Xaml
<Image Source="{Binding ImageSource}" Aspect="AspectFit" ></Image>
在代码中
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"))
}
};
结果
更新
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).
有关详细信息,请查看答案
现在如果你想显示一张图片而不添加到每个平台,你应该使用Converter。
例如:
在共享代码中创建一个名为 ImagesFolder
的新文件夹,然后将图像添加到其中
在代码中,创建一个名为 ByteArrayToImageSourceConverter
的新 class,如下所示
public 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;
}
}
查看模型
public ObservableCollection<Item> MediaList { get; set; } = new ObservableCollection<Item>()
{
new Item
{
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>
<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>
相关链接
ByteArrayToImageSourceConverter
我有一个 ObservableCollection<Item>
和一个 Item
包含文件路径和磁盘中某些图像的 ImageSource
。
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; }
}
但是,我无法访问这两个属性中的任何一个,也无法通过 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>
现在我很困惑,因为我可以通过标签通过 XAML 输出 string Image
,但根本无法显示路径中的图像。
将 ImageSource
类型更改为 String
public class Item
{
public string ImageSource { get; set; }
}
用法
List<Item> items = new List<Item>();
items.Add(new Item() { ImageSource = "*THE URL OF IMAGE*" });
ListView.ItemsSource = items;
您可以像这样使用 ImageSource.FromFile()
或 ImageSource.FromUri()
在Xaml
<Image Source="{Binding ImageSource}" Aspect="AspectFit" ></Image>
在代码中
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"))
}
};
结果
更新
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).
有关详细信息,请查看答案
现在如果你想显示一张图片而不添加到每个平台,你应该使用Converter。
例如:
在共享代码中创建一个名为
ImagesFolder
的新文件夹,然后将图像添加到其中在代码中,创建一个名为
ByteArrayToImageSourceConverter
的新 class,如下所示public 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; } }
查看模型
public ObservableCollection<Item> MediaList { get; set; } = new ObservableCollection<Item>() { new Item { 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> <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>
相关链接
ByteArrayToImageSourceConverter