Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在TableView中绑定从磁盘加载的映像';什么是可视单元?_C#_Xamarin.android_Xamarin.forms - Fatal编程技术网

C# 如何在TableView中绑定从磁盘加载的映像';什么是可视单元?

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

以下是我正在做的:

我将占位符图像设置为ViewCell的子类图像

然后,将图像从磁盘加载到替换占位符

这对占位符很好,但是,在设置磁盘中的图像后(正确显示),如果我滚动出视图,然后返回,则会出现以下错误:

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;
        }

    }

}