Xamarin中BindableLayout绑定的图片列表如何获取文件名及流上传
问题根因
你当前存储的ImageSource是Xamarin中用于UI渲染的抽象图片源类,本身不包含原始选中文件的文件名、文件流读取等属性和方法,因此无法直接调用FileName和OpenReadAsync()。
解决方法
我们只需要自定义一个承载图片全量信息的模型类,替换原来的List<ImageSource>即可,步骤如下:
1. 新增自定义图片模型类
public class UploadImageModel { // 用于UI显示的图片源 public ImageSource DisplaySource { get; set; } // 原始选中的文件对象,保留读取流、文件名的能力 public MediaFile SelectedFile { get; set; } }
2. 修改XAML绑定路径
原来的BindableLayout中Image的绑定需要改绑模型的DisplaySource属性:
<Image HeightRequest="70" WidthRequest="70" Aspect="AspectFill" Source="{Binding DisplaySource}"/>
3. 修改后台代码逻辑
替换列表类型,同步修改选择、上传逻辑:
// 替换原来的List<ImageSource> List<UploadImageModel> imgList = new List<UploadImageModel>(); async void pickimg_Tapped(System.Object sender, EventArgs e) { var pickResult = await MediaGallery.PickAsync(5, MediaFileType.Image); if(pickResult?.Files == null) { return; } else { foreach (var img in pickResult.Files) { var stream = await img.OpenReadAsync(); imgList.Add(new UploadImageModel { DisplaySource = ImageSource.FromStream(() => stream), SelectedFile = img }); } BindableLayout.SetItemsSource(listImg, imgList); } } private async void bt_addfeed_Clicked(object sender, EventArgs e) { if (!imgList.Any()) { return; } // HttpClient建议复用,不要每次循环新建 using var httpClient = new HttpClient(); foreach(var img in imgList) { var content = new MultipartFormDataContent(); // 直接从保留的原始文件对象取信息 var fileStream = await img.SelectedFile.OpenReadAsync(); content.Add(new StreamContent(fileStream), "file", img.SelectedFile.FileName); var response = await httpClient.PostAsync("xxxx/api/UploadFileFeeds", content); // 这里可以自行补充响应结果校验、失败重试等逻辑 } // 上传完成后可按需清空imgList和展示列表 }
额外优化建议
- 如果需要一次上传多张图片,可以把多个
StreamContent都加到同一个MultipartFormDataContent中,只发起一次POST请求,减少性能损耗 - 上传过程建议加Loading弹窗提示用户,避免用户重复点击提交
内容的提问来源于stack exchange,提问作者Chim Di Tru
相关产品推荐
相关产品推荐

