C# 如何在TableView中绑定从磁盘加载的映像';什么是可视单元?
以下是我正在做的: 我将占位符图像设置为ViewCell的子类图像 然后,将图像从磁盘加载到替换占位符 这对占位符很好,但是,在设置磁盘中的图像后(正确显示),如果我滚动出视图,然后返回,则会出现以下错误:C# 如何在TableView中绑定从磁盘加载的映像';什么是可视单元?,c#,xamarin.android,xamarin.forms,C#,Xamarin.android,Xamarin.forms,以下是我正在做的: 我将占位符图像设置为ViewCell的子类图像 然后,将图像从磁盘加载到替换占位符 这对占位符很好,但是,在设置磁盘中的图像后(正确显示),如果我滚动出视图,然后返回,则会出现以下错误: Cannot access a disposed object. Object name: 'Stream has been closed'. 堆栈跟踪: at System.IO.FileStream.Read (System.Byte[] array, System.Int32 off
Cannot access a disposed object.
Object name: 'Stream has been closed'.
堆栈跟踪:
at System.IO.FileStream.Read (System.Byte[] array, System.Int32 offset, System.Int32 count) [0x0000d] in <d18287e1d683419a8ec3216fd78947b9>:0
at Android.Runtime.InputStreamAdapter.Read (System.Byte[] bytes, System.Int32 offset, System.Int32 length) [0x00006] in <33e6e739ac344166b157e323586f11a1>:0
at Java.IO.InputStream.n_Read_arrayBII (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_b, System.Int32 off, System.Int32 len) [0x00019] in <33e6e739ac344166b157e323586f11a1>:0
at (wrapper dynamic-method) System.Object:c31b04e7-d4e0-4108-9aaf-784714d6a934 (intptr,intptr,intptr,int,int)
Page.xaml.cs
private async Task SetTableView()
{
var profileCell = new UserProfileCell();
profileCell.Photo.BindingContext = viewModel;
profileCell.Photo.SetBinding(Image.SourceProperty, new Binding("ProfilePhoto", BindingMode.OneWay));
var tableSections = new List<TableSection>();
tableSections.Add(new TableSection()
{
profileCell
});
Content = new TableView
{
HasUnevenRows = true,
Intent = TableIntent.Menu,
Root = new TableRoot()
{
tableSections
}
};
await viewModel.LoadProfilePhoto();
}
private异步任务SetTableView()
{
var profileCell=new UserProfileCell();
profileCell.Photo.BindingContext=viewModel;
profileCell.Photo.SetBinding(Image.SourceProperty,新绑定(“ProfilePhoto”,BindingMode.OneWay));
var tableSections=新列表();
添加(新的TableSection()
{
轮廓细胞
});
内容=新的表格视图
{
HasRows=true,
Intent=TableIntent.Menu,
Root=newtableroot()
{
表节
}
};
等待viewModel.LoadProfilePhoto();
}
从磁盘读取照片的代码:
public async Task<ImageSource> GetPhoto(string fileName)
{
var localStorage = FileSystem.Current.LocalStorage;
var folderExists = await localStorage.CheckExistsAsync(PhotosFolder);
if (!folderExists.Equals(ExistenceCheckResult.FolderExists))
return null;
var localStorageFolder = await localStorage.GetFolderAsync(PhotosFolder);
var fileExists = await localStorageFolder.CheckExistsAsync(fileName);
if (!fileExists.Equals(ExistenceCheckResult.FileExists))
return null;
IFile file = await localStorageFolder.GetFileAsync(fileName);
if (file == null)
return null;
var stream = await file.OpenAsync(FileAccess.Read);
var imageSource = ImageSource.FromStream(() => stream);
return imageSource;
}
public异步任务GetPhoto(字符串文件名)
{
var localStorage=FileSystem.Current.localStorage;
var folderExists=await localStorage.CheckExistsAsync(photoFolder);
如果(!folderExists.Equals(ExistenceCheckResult.folderExists))
返回null;
var localStorageFolder=await localStorage.GetFolderAsync(photofolder);
var fileExists=await localStorageFolder.CheckExistsAsync(文件名);
如果(!fileExists.Equals(ExistenceCheckResult.fileExists))
返回null;
IFile file=await localStorageFolder.GetFileAsync(文件名);
if(file==null)
返回null;
var stream=await file.OpenAsync(FileAccess.Read);
var imageSource=imageSource.FromStream(()=>stream);
返回图像源;
}
现在这只发生在Android上。我在iOS上遇到了这个问题,但在使用占位符后,问题就消失了
现在它只发生在Android上。我用的是Xamarin.Forms
我做错了什么
感谢根据我收集的信息,Xamarin将尝试处理不再使用的流 为了解决这个问题,正如建议的那样 我将上述代码从GetPhoto修改为GetPhotoBytes: 现在,我不再使用文件中的流,而是从Photo字节创建一个新的流。我还不明白为什么这个流没有被处理。然而,就目前而言,它似乎工作正常
public async Task<ImageSource> GetPhoto(string fileName)
{
var localStorage = FileSystem.Current.LocalStorage;
var folderExists = await localStorage.CheckExistsAsync(PhotosFolder);
if (!folderExists.Equals(ExistenceCheckResult.FolderExists))
return null;
var localStorageFolder = await localStorage.GetFolderAsync(PhotosFolder);
var fileExists = await localStorageFolder.CheckExistsAsync(fileName);
if (!fileExists.Equals(ExistenceCheckResult.FileExists))
return null;
IFile file = await localStorageFolder.GetFileAsync(fileName);
if (file == null)
return null;
var stream = await file.OpenAsync(FileAccess.Read);
var imageSource = ImageSource.FromStream(() => stream);
return imageSource;
}
public async Task<byte[]> GetPhotoBytes(string fileName)
{
var localStorage = FileSystem.Current.LocalStorage;
var folderExists = await localStorage.CheckExistsAsync(PhotosFolder);
if (!folderExists.Equals(ExistenceCheckResult.FolderExists))
{
return null;
}
var localStorageFolder = await localStorage.GetFolderAsync(PhotosFolder);
var fileExists = await localStorageFolder.CheckExistsAsync(fileName);
if (!fileExists.Equals(ExistenceCheckResult.FileExists))
{
return null;
}
IFile file = await localStorageFolder.GetFileAsync(fileName);
if (file == null)
{
return null;
}
var stream = await file.OpenAsync(FileAccess.Read);
byte[] bytes = null;
using (var memoryStream = new System.IO.MemoryStream())
{
stream.CopyTo(memoryStream);
stream.Dispose();
bytes = memoryStream.ToArray();
}
return bytes;
}
public async Task LoadProfilePhoto()
{
// Set placeholder first
ProfilePhoto = ImageSource.FromFile(FileNames.ProfilePlaceholderPNG);
// Attemp to load existing photo
var photoBytes = await Storage.Current.GetPhotoBytes(FileNames.ProfilePictureJPG);
if (photoBytes != null)
{
var photo = ImageSource.FromStream(() => new System.IO.MemoryStream(photoBytes));
if (photo != null)
{
ProfilePhoto = photo;
}
}
}