I am trying to load images in a collection view in .NET MAUI but they are not showing. The images have to be retrieved via URL or from disk, depending if they have been downloaded already. I am trying to update the image path after the ForecastData object is created in the QueryApi method. The collectionview loads the text information fine but not the images. Under every weather description there should be a small 100x100 icon for the weather.
我正尝试在.NET毛伊岛的收藏视图中加载图像,但它们没有显示。这些图像必须通过URL或从磁盘检索,这取决于它们是否已经下载。我正在尝试在QueryApi方法中创建ForecastData对象后更新图像路径。集合视图可以很好地加载文本信息,但不能加载图像。在每个天气描述下,都应该有一个小的100x100的天气图标。
This approach works for page in my application when a single weather object is used but I cannot seem to get it to work in a collection view. An obvious workaround is to include the images at compile time but I would prefer to fetch the icons at runtime
当使用单个天气对象时,这种方法适用于我应用程序中的页面,但我似乎无法使其在集合视图中工作。一个明显的解决办法是在编译时包含图像,但我更喜欢在运行时获取图标
Page
页面
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WeatherApp.Pages.ForecastWeatherPage"
Title="5-Day Forecast">
<VerticalStackLayout Margin="20"
Spacing="40">
<Entry Placeholder="ZIP"
Text="{Binding ZipCode}"
MaxLength="5"
WidthRequest="200"
HeightRequest="40"
HorizontalOptions="Center"
VerticalOptions="Center"
ClearButtonVisibility="WhileEditing" />
<Label x:Name="CityLabel"
FontSize="40"
HorizontalOptions="Center"
TextColor="Gray"
Text="{Binding CityName}" />
<CollectionView ItemsSource="{Binding WeatherForecast}"
ItemsLayout="HorizontalList"
HorizontalScrollBarVisibility="Always">
<CollectionView.ItemTemplate>
<DataTemplate>
<VerticalStackLayout Margin="20"
Spacing="40">
<Label x:Name="WeatherDescriptionLabel"
FontSize="Medium"
HorizontalOptions="Center"
TextColor="SlateGray"
Text="{Binding WeatherDescription}" />
<Image Source="{Binding WeatherImagePath}"
Aspect="AspectFit"
MaximumHeightRequest="100"
MaximumWidthRequest="100" />
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ContentPage>
view model
查看模型
using WeatherApp.Services;
using WeatherApp.Models.ForecastWeatherModel;
using ForecastData = WeatherApp.Models.WeatherDataObject;
using System.Collections.ObjectModel;
using WeatherApp.Pages;
namespace WeatherApp.ViewModels
{
public class ForecastWeatherViewModel : BaseViewModel
{
private string zipCode;
private string cityName;
private Root weatherForecastRoot;
public ObservableCollection<ForecastData> WeatherForecast { get; private set; } = new ObservableCollection<ForecastData>();
public ForecastWeatherViewModel()
{
weatherForecastRoot = new Root();
zipCode = string.Empty;
cityName = "Please Enter Zip Code";
}
public string ZipCode
{
get => zipCode;
set
{
SetProperty(ref zipCode, value);
if (zipCode.Length == 5)
{
QueryApi();
}
}
}
public string CityName
{
get => cityName;
set
{
SetProperty(ref cityName, value);
}
}
private async void QueryApi()
{
if (int.TryParse(zipCode, out var convertedZipCode))
{
weatherForecastRoot = await ApiService.GetWeatherForecast(convertedZipCode);
if (weatherForecastRoot != null)
{
CityName = weatherForecastRoot.city.name;
List<ForecastData> preparationList = new List<ForecastData>();
foreach(var weatherReport in weatherForecastRoot.list)
{
foreach(var report in weatherReport.weather)
{
ForecastData weatherDataObject = new ForecastData(report.description, report.icon);
if (!FileService.isIconDownloaded(weatherDataObject.WeatherIcon))
{
byte[] imageByteArray = await ApiService.GetWeatherImageFromIconCode(weatherDataObject.WeatherIcon);
weatherDataObject.WeatherImagePath = FileService.SaveIconToAppData(imageByteArray, weatherDataObject.WeatherIcon);
}
else
{
weatherDataObject.WeatherImagePath = FileService.GetIconPath(weatherDataObject.WeatherIcon);
}
preparationList.Add(weatherDataObject);
}
}
WeatherForecast = new ObservableCollection<ForecastData>(preparationList);
OnPropertyChanged(nameof(WeatherForecast));
}
else
{
CityName = "Cannot locate city/region by zip code";
}
}
}
}
}
更多回答
if that is a valid image path I'd expect it to work. If you put a standalone Image
control at the bottom of the page and assign it one of the paths, does that work?
如果这是一个有效的图像路径,我希望它可以工作。如果您在页面底部放置一个独立的Image控件,并为其分配一个路径,这是否起作用?
its a valid path and if i replace the binding with something on disk or on a site it appears in the collection view
这是一个有效的路径,如果我用磁盘或站点上的内容替换绑定,它就会出现在集合视图中
are you using OpenWeatherMap? If not, which API are you using?
您是否在使用OpenWeatherMap?如果不是,您使用的是哪种API?
Why aren’t you just using the url of the image instead of downloading it?
为什么你不直接使用图片的url而不是下载它呢?
优秀答案推荐
First: It is not a correct path.
第一:这不是一条正确的道路。
I am 99.99% sure that for icon you have something like this: "01d"
Instead of something like:http://openweathermap.org/img/wn/[email protected]
我99.99%确定图标的值是这样的:“01D”,而不是这样:http://openweathermap.org/img/wn/[email,Protected]
Second: This is not going to render in release at all.
At this line: <DataTemplate>
you HAVE TO specify the type you are using.
第二:这根本不会在发行版中呈现。在该行:
,您必须指定您正在使用的类型。
Third: (this is only recommended) I would have used Width/HeightRequest.
Third:(这只是推荐的)我会使用Width/HeightRequest.
Setting HeightRequest="400" in the collection view revealed the icons. Lesson
Learned.
在集合视图中设置HeightRequest值=“400”将显示图标。吸取了教训。
<CollectionView ItemsSource="{Binding WeatherForecast}"
ItemsLayout="HorizontalList"
HorizontalScrollBarVisibility="Always"
HeightRequest="400">
<CollectionView.ItemTemplate>
<DataTemplate>
<VerticalStackLayout Margin="20"
Spacing="40">
<Label x:Name="WeatherDescriptionLabel"
FontSize="Medium"
HorizontalOptions="Center"
TextColor="SlateGray"
Text="{Binding WeatherDescription}" />
<Image Source="{Binding WeatherImagePath}"
Aspect="AspectFit"
MaximumHeightRequest="200"
MaximumWidthRequest="200" />
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
更多回答
the icon code is separate from the image path here, FileService returns a path to the image file on disk after it is fetched by ApiService. It works when using open weathers current weather API without collection view. I am not following you on the DataTemplate issue. That is being done in ItemSource and the weather description renders just fine.
图标代码与这里的图像路径是分开的,FileService在ApiService获取图像文件后返回磁盘上的图像文件的路径。它在没有集合视图的情况下使用开放天气当前天气API时起作用。在数据模板问题上,我不会跟您走。这是在ItemSource中完成的,并且天气描述呈现得很好。
我是一名优秀的程序员,十分优秀!