如何在.NET MAUI中通过表单传递图片URI并在菜品列表页显示图片?
.NET MAUI 菜品食谱图片URI传递与列表展示实现步骤
1. 确认模型字段
你已经将图片字段定义为字符串类型,确保你的Recipe模型包含该属性:
public class Recipe { public int Id { get; set; } public string Name { get; set; } public string Ingredients { get; set; } // 存储图片本地路径或网络URI public string ImageUri { get; set; } }
2. 录入页面:添加图片选择与绑定
修改录入页的XAML,增加图片预览和选择按钮,并绑定到ViewModel的对应属性:
<VerticalStackLayout> <Label Text="Name" FontSize="16"/> <Entry Text="{Binding RecipeDetails.Name}" Placeholder="Meal"/> <!-- 图片预览区域 --> <Image Source="{Binding RecipeDetails.ImageUri}" Aspect="AspectFill" HeightRequest="200" WidthRequest="200" Margin="0,10"/> <!-- 触发图片选择的按钮 --> <Button Text="选择菜品图片" Command="{Binding PickImageCommand}" Margin="0,10"/> </VerticalStackLayout>
在ViewModel中实现图片选择逻辑,将选中的图片保存到应用私有目录(避免原始文件被删除导致图片失效),并赋值给RecipeDetails.ImageUri:
public class RecipeAddViewModel : INotifyPropertyChanged { public ICommand PickImageCommand { get; } public Recipe RecipeDetails { get; set; } = new Recipe(); public RecipeAddViewModel() { PickImageCommand = new Command(async () => await PickImageAsync()); } private async Task PickImageAsync() { var pickResult = await FilePicker.PickAsync(new PickOptions { PickerTitle = "选择菜品图片", FileTypes = FilePickerFileType.Images }); if (pickResult != null) { // 将图片复制到应用私有存储目录 var targetPath = Path.Combine(FileSystem.AppDataDirectory, pickResult.FileName); using var sourceStream = await pickResult.OpenReadAsync(); using var targetStream = File.OpenWrite(targetPath); await sourceStream.CopyToAsync(targetStream); // 更新模型的ImageUri字段 RecipeDetails.ImageUri = targetPath; OnPropertyChanged(nameof(RecipeDetails)); } } // 实现INotifyPropertyChanged接口(略) public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
3. 保存到数据库
保存逻辑和你之前处理菜品名称、配料的流程一致,只需确保ImageUri字段被包含在数据库操作中。比如用EF Core的话,确保实体配置已映射该字段;用SQLite的话,表结构要有对应的ImageUri列。
4. 列表页面展示图片
在菜品列表页的CollectionView(或ListView)的ItemTemplate中,用Image控件绑定Recipe.ImageUri即可,同时可添加加载失败的 fallback:
<CollectionView ItemsSource="{Binding Recipes}"> <CollectionView.ItemTemplate> <DataTemplate> <HorizontalStackLayout Padding="10" Spacing="10"> <Image Source="{Binding ImageUri}" Aspect="AspectFill" HeightRequest="80" WidthRequest="80"> <!-- 图片加载失败时显示默认图 --> <Image.Error> <EventCallback> <Setter Property="Source" Value="default_meal.png"/> </EventCallback> </Image.Error> </Image> <VerticalStackLayout> <Label Text="{Binding Name}" FontSize="16" FontAttributes="Bold"/> <Label Text="{Binding Ingredients}" FontSize="14" TextColor="Gray"/> </VerticalStackLayout> </HorizontalStackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
关键注意事项
- 权限配置:
- Android:在
Platforms/Android/AndroidManifest.xml中添加权限<!-- Android 13+ --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- 兼容Android 12及以下 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> - iOS:在
Platforms/iOS/Info.plist中添加相册访问说明<key>NSPhotoLibraryUsageDescription</key> <string>需要访问相册选择菜品图片</string>
- Android:在
- 若需支持网络图片,直接将
ImageUri设为网络URL即可,Image控件会自动加载。
内容的提问来源于stack exchange,提问作者edodoe
相关产品推荐
相关产品推荐

