Xamarin - 异步数据绑定

2024-03-08

我有以下代码:

包含大量图像的页面,通过数据绑定动态加载:

 base.OnAppearing();
        if (!loaded)
        {
            loaded = true;

            BindingContext = new GalleryViewModel(pCode, gCode, gUrl);

        }

视图模型:

namespace GalShare.ViewModel
{
class GalleryViewModel
{
    public string pCode { get; set; }
    public string gCode { get; set; }
    public string gUrl { get; set; }
    public ObservableCollection<picdata> Galleries { get; set; }          
    public  GalleryViewModel(string pCode, string gCode, string gUrl)
    {
        this.pCode = pCode;
        this.gCode = gCode;
        this.gUrl = gUrl;
        Galleries = new GalleryService().GetImageList(pCode,gCode,gUrl);

    }

}
}

galleryservice.cs

   class GalleryService
 {

    public ObservableCollection<picdata> Images { get; set; }
    public ObservableCollection<picdata> GetImageList(string pCode, string gCode, string gUrl)
    {
        WebClient client = new WebClient();
        Images = new ObservableCollection<picdata>();
        string downloadString = client.DownloadString(gUrl);
        var deserialized = JsonConvert.DeserializeObject<JsonTxt>(downloadString);

            foreach (File img in deserialized.Files)
            {
               Images.Add(new picdata()
               {
                    ImageName = img.file,
                    BaseUrl = deserialized.Settings.Path.ToString(),
                    ThumbUrl = deserialized.Settings.Path.ToString() + "/thumbs" + img.file
               });
            }
        return Images;
    }
}

页面的 XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:vm="clr-namespace:GalShare.ViewModel"
         xmlns:d="http://xamarin.com/schemas/2014/forms/design"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
         mc:Ignorable="d"
         x:Class="GalShare.Views.Gallery">

<StackLayout>
    <CollectionView ItemsSource="{Binding Galleries}" x:Name="myCollection" SelectionMode="Single" SelectionChanged="CollectionView_SelectionChanged">
        <CollectionView.ItemsLayout>
            <GridItemsLayout Orientation="Vertical"
                    Span="2" />
        </CollectionView.ItemsLayout>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <ffimageloading:CachedImage Source="{Binding ThumbUrl}" CacheDuration="1" HorizontalOptions="Fill" VerticalOptions="Fill" DownsampleToViewSize="False"></ffimageloading:CachedImage>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</StackLayout>

</ContentPage>

该代码有效,但考虑到图像是从网络加载的,当我加载数据时,应用程序被锁定。如何异步完成此操作?我想加载目标页面,然后在我在那里时加载内容。目前,应用程序冻结在加载此页面的页面上,直到所有内容都加载完毕。

我尝试过任务/等待但没有成功。我想我必须移动一些东西才能异步运行代码,但不知道如何操作。


您已标记async-await并在标题中写入异步。但是,所有代码都在主线程上运行,而不是异步运行。

而不是在 ViewModel 的构造函数中加载数据。我强烈建议您使用生命周期事件,例如OnAppearing在你的Page并开火ICommand异步加载数据。

另外我会改用HttpClient及其漂亮的异步 API。所以像这样:

public class GalleryService
{
    private HttpClient _httpClient;

    public GalleryService()
    {
        _httpClient = new HttpClient();
    }

    public async Task<IEnumerable<picdata>> GetImageList(string pCode, string gCode, string gUrl)
    {
        var response = await _httpClient.GetAsync(gUrl).ConfigureAwait(false);
        if (response.IsSuccessStatusCode)
        {
            var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            var deserialized = JsonConvert.DeserializeObject<JsonTxt>(json);

            var images = new List<picdata>();
            foreach(var img in deserialized.Files)
            {
                images.Add(new picdata()
                {
                    ImageName = img.file,
                    BaseUrl = deserialized.Settings.Path.ToString(),
                    ThumbUrl = deserialized.Settings.Path.ToString() + "/thumbs" + img.file
                });
            }

            return images;
        }

        return new picdata[0]; // return empty set
    }
}

和视图模型:

public class GalleryViewModel
{
    private GalleryService _galleryService;

    public ObservableCollection<picdata> Galleries { get; } = new ObservableCollection<picdata>();
    public ICommand GetImagesCommand { get; }

    public GalleryViewModel(string pCode, string gCode, string gUrl)
    {
        _galleryService = new GalleryService();

        GetImagesCommand = new Command(async () => DoGetImagesCommand(pCode, gCode, gUrl));
    }

    private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl)
    {
        var images = await _galleryService.GetImageList(pCode, gCode, gUrl);
        foreach(var image in images)
            Galleries.Add(image);
    }
}

然后在你的OnAppearing()在您的页面上覆盖,您可以调用类似以下内容的内容:(BindingContext as GalleryViewModel).GetImagesCommand.Execute(null);

确保您设置了BindingContext在尝试调用命令之前。这可以在 Page 构造函数中完成:

BindingContext = new GalleryViewModel();

这样,在图像下载完成之前,您就不会阻塞整个 UI。或者,您可以使用以下命令启动任务Task.Run在 ViewModel 的构造函数中。但是,您必须将 ObservableCollection 的数量编组到 UI 线程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Xamarin - 异步数据绑定 的相关文章

  • 如何使实体框架存储过程异步?

    我有一个函数 ReturnStatementDetailsForSubRepAsync 它使用一个 linq 表达式 我可以使用内置函数轻松地使其异步 例如 ToListAsync 现在 因为此 LINQ 函数是异步的 所以我必须使父函数异
  • .GetAwaiter() 和ConfigureAwait() 之间的区别[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 谁能告诉我两者之间的区别GetAwaiter and ConfigureAwait false 两者都用在Async方法中来解决死锁情
  • 在没有 TransactionScopeAsyncFlowOption.Enabled 的情况下启用异步 TransactionScope

    以下是使用事务范围的异步缓存和数据库更新 我无法使用TransactionScopeAsyncFlowOption Enabled在 v 4 5 1 中引入 因为我使用的 Apache Ignite Net 缓存不支持它 我尝试通过捕获当前
  • Xamarin - 未找到类(Android 支持库)

    我正在尝试使用 AppCompat 实现具有向后兼容性的 Material Design 继tutorial https blog xamarin com android tips hello material design v7 appc
  • 浏览器中的javascript:异步任务执行模型

    我正在尝试集中注意力并了解 javascript 异步在单线程浏览器环境中的工作原理 作为异步 我们可以同时处理计时器和 xhr 请求 现在假设我有类似下面的东西 function doStuff for var i 0 i lt 1000
  • Angularjs $http 等待响应

    我是 javascript angularjs 的新手 我想在某些元素上完成鼠标悬停时显示引导弹出窗口 我为此创建了一个指令 function angular app app directive popOver window http fu
  • Android 上的 Xamarin.Forms“应用程序已停止工作”

    所以我刚才遇到了这个错误 这导致我的 Android 应用程序无法在设备上运行 每当我调试 Android 应用程序时 它都会因某种原因崩溃 作为 Xamarin 的新用户 我一无所知 这是我收到的错误 art Late enabling
  • 在 MonoDroid 中设置 textview 的文本时,“jobject”不能为 IntPtr.Zero

    我将 MvvmCross 与 MonoDroid 一起使用 在视图模型中的计时器中 我每分钟调用RaisePropertyChanged MinutesRemaining MinutesRemaining是一个整数 指定当前条目结束之前的持
  • WPF 中 ToggleButton 的 IsChecked 属性的 OneWay 绑定

    我有一个ToggleButton以其IsChecked使用 OneWay 绑定将属性绑定到属性
  • WPF 中的数据绑定?

    我正在尝试在 WPF 中设置数据绑定 我有班级人员 它通过一个文本框进行更新 类似老式的 另一个文本框应该通过数据绑定镜像对人员对象的更改 它曾经是 type twoway 但抛出了xamlparse 异常 它不是这样工作的 点击显示 pe
  • async.js 和系列问题

    连接后尝试运行 fetch 提取比连接更快 并且在控制台中我收到提取错误 因为它返回结果的速度比连接完成的速度快 但在异步系列的文档中 有一个工具可以在第一个返回结果后运行第二个函数 Settimeouts 可以保存情况 但它并不美观 当一
  • 所有 C++ 编译器都支持 async/await 关键字吗?

    我想用async awaitC UE4 框架 中的语法 但由于跨平台代码 我不确定这是否可能 或者可能 如果是 我该如何使用它 而且还有await and await resumable yield and yield value另外 在
  • 如何使用 C#8 IAsyncEnumerable 异步枚举并行运行的任务

    如果可能的话 我想为并行启动的任务创建一个异步枚举器 因此 首先完成的是枚举的第一个元素 第二个完成的是枚举的第二个元素 依此类推 public static async IAsyncEnumerable
  • 带有 ObservableCollection 和动态过滤器的 Silverlight ListBox

    假设我有这门课 public class MyData public bool IsActive get set public String Data1 get set public String Data2 get set and an
  • 将 WPF 快捷键绑定到 ViewModel 中的命令

    我有一个使用 MVVM 模式的 WPF 应用程序 将按钮连接到 VM 非常简单 因为它们实现了 ICommand 我有一个工作原理类似的上下文菜单 下一步是为上下文菜单创建快捷键 我不知道如何让快捷键调用命令 这是一个例子
  • 如何启动异步任务对象

    我想开始收集Task同时处理对象并等待所有对象完成 下面的代码显示了我想要的行为 public class Program class TaskTest private Task createPauseTask int ms works w
  • 使用异步工作流程并行化的最佳实践

    假设我想抓取一个网页并提取一些数据 我很可能会写这样的东西 let getAllHyperlinks url string async let req WebRequest Create url let rsp req GetRespons
  • 获取代码中的绑定结果

    我可能正在以错误的方式寻找这个 但是 有没有办法通过代码获取绑定的结果值 可能是一些显而易见的东西 但我就是找不到它 您只需致电ProvideValue的绑定方法 困难的部分是你需要通过有效的IServiceProvider到方法 编辑 实
  • 未捕获 Func<> 的异常(异步)

    我有以下代码 为了进行此重现而进行了简化 显然 catch 异常块将包含更多逻辑 我有以下代码 void Main var result ExecuteAction async gt Will contain real async code
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr

随机推荐

  • jQuery 将类添加到图像链接,而不会在链接传递变量时弄乱

    好的 所以我使用了一些 jquery 来选择所有 a 页面上的标签以及它们是否链接到图像文件以添加zoom出于灯箱的目的对其进行类处理 这是有效的代码 document ready function a href png a href gi
  • List<>.IndexOf 是按引用还是按值进行比较?

    List
  • ant+cpptasks 与 scons 与 make

    我正在调查scons http www scons org 我只是想确保在我将大量脑细胞投入到完全不同的事物之前我知道替代方案是什么 我过去一直在使用 GNU make 但从来没有对它感到特别满意 特别是 为什么 Ant 没有更频繁地用于
  • 使用固定装置返回值作为 mark.parametrize() 中的值

    我的问题是 是否可以使用夹具的返回值作为参数化中的值 问题是 我想动态获取参数化的可能值 例如 虚拟服务器上的可用系统 当其中一个设备创建虚拟服务器时 我可以访问这些 测试看起来像这样 伪代码 conftest py pytest fixt
  • iOS 7:自定义容器视图控制器和内容插入

    我有一个封装在导航控制器中的表视图控制器 当通过以下方式呈现时 导航控制器似乎会自动将正确的内容插入应用到表视图控制器presentViewController animated completion 谁能向我解释一下它到底是如何工作的 但
  • Paypal 结帐中无法访问 iframe 元素 id 的异常处理

    我有一个电子商务网站 当我尝试下订单时 它会重定向到 Paypal 页面 当我以 Paypal 用户身份登录时 它会重定向到另一个结账屏幕 我在其中尝试使用 selenium Web 驱动程序进行自动化 在此步骤中 出现以下异常 我尝试使用
  • 如何在数据库中保存跟踪折线?

    我创建了一个功能 可以跟踪用户的路线并创建折线 我一直在尝试将其保存到 Firebase 路线 ID 路线名称 纬度 经度 我使用的方法是 每次位置更改时 用户的新纬度和经度都会保存到 Firebase 用户设置的路线名称和 当前 静态路线
  • 在 Play Slick 中分配动态注入的数据库名称

    我有以下 Play Slick DAO 课程 注意数据库配置是一个常量control0001 DAO 有一个功能readUser根据用户 ID 读取用户 class UsersDAO Inject NamedDatabase control
  • Angular 5 HttpClient 与之前的 Http 相比有哪些优势?

    我阅读了官方升级指南 上面写着 因为 HttpClient 得到广泛采用 我们决定 但是这个 HttpClient 带来的真正好处是什么 我正在考虑尝试一下 但中途感到困惑 因为我不知道升级后这些需要发生什么 从 angular http
  • 使用 nginx 的子目录中的 CakePHP(重写规则?)

    不久前我设法让它工作 但是当我回到我开始的 cakephp 项目时 似乎我最近对 nginx 所做的任何更改 或者可能是最近的更新 都打破了我的重写规则 目前我有 worker processes 1 events worker conne
  • Angular cli 项目中的绝对路径

    如何在 Angular cli 生成的项目中使用绝对路径 所以我有这条路 src gt app gt shared我想写import from shared ffdsdf my module ts 代替 shared ffdsdf my m
  • 将 dynamodb 表复制到 hive 的 pyspark 代码问题:不允许操作

    我正在尝试使用 pyspark 代码从 aws emr 上的 Dynamodb 创建外部配置单元表 当我在 hive 提示符下执行查询时 该查询工作正常 但当我将其作为 pyspark 作业执行时 该查询会失败 代码如下 from pysp
  • 本地开发主机的通配符

    我最近在多个项目之间切换 所有这些都在相同的IP上本地运行 但具有不同的域 实际上它总是 local like foo local bar local等等 我可以继续将它们添加到我的 etc hosts文件 但这不是很干净的方式 这就是为什
  • 我无法在 Android AVD Manager 中创建模拟器

    我正在尝试创建一个 Android 模拟器 当我打开 AVD 管理器并尝试创建一个模拟器时 它一直显示 未选择目标 即使我选择了目标 http bit ly 15vr9fk http bit ly 15vr9fk 面临同样的问题 我检查了A
  • 未收到 Microsoft Graph 更改通知

    我想订阅用户删除 以便每当在 Azure AD 中删除用户时 我们的应用程序都可以做出相应的反应 这是我的订阅请求 const now new Date const threeDaysLater new Date now getTime 3
  • unix fork exec 序列真的像听起来那么昂贵吗?

    我正在读关于fork and exec对于考试 我的书说 每当需要在 UNIX 系统中运行一个新的 不同的 进程时 您都会分叉当前进程 然后是execve 然而 它也说 每当fork被调用时 父进程的整个内存映像被复制到新进程 那么我的问题
  • 是否可以通过在基类中添加新的虚函数来破坏代码?

    是否可以通过简单地向基类添加新的虚函数来改变程序的观察到的行为 我的意思是不必对代码进行其他更改 以下程序打印OK 取消注释虚函数B它将开始打印CRASH include
  • 如何使用 JavaScript 创建电子邮件按钮

    我找不到真正符合我的问题的帖子 所以我们开始 我想在我的网站上实现 通过邮件共享 按钮 因此当您单击该按钮时 假设 Outlook 或 Thunderbird 打开 并为您提供在新邮件中共享网站链接的选项 我不太确定 但我认为我无法仅使用
  • 将带孔的多边形转换为多个简单的无孔多边形

    我正在处理IfcFace http www buildingsmart tech org ifc IFC4 Add2 html schema ifctopologyresource lexical ifcface htm 我得到了一个带孔的
  • Xamarin - 异步数据绑定

    我有以下代码 包含大量图像的页面 通过数据绑定动态加载 base OnAppearing if loaded loaded true BindingContext new GalleryViewModel pCode gCode gUrl