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 - 异步数据绑定 的相关文章

  • 如何使用 AFNetworking 2 按严格的顺序发送请求?

    我正在进行同步以将 sqlite 数据库镜像到服务器数据库 我有一个主从表 其中的详细信息必须尽快发送到服务器 但是 细节 3 可能会先于细节 2 到达 我需要模仿对文档执行的步骤并尊重操作的顺序 当记录保存在本地时 我会发送通知 然后发布
  • 我可以在 Play Framework 2.x (Scala) 中进行异步表单验证吗?

    我正在努力了解 Play 的异步功能 但发现在异步调用适合的地方以及框架似乎密谋反对其使用的地方存在很多冲突 我的例子与表单验证有关 Play 允许定义临时约束 请参阅文档 val loginForm Form tuple email gt
  • 为什么这行带有“await”的代码会触发微任务队列处理?

    以下引用是我理解微任务队列处理的主要参考 当 JS 堆栈清空时 就会处理微任务 承诺使用 杰克 阿奇博尔德 https twitter com jaffathecake status 954653170986311680 这对我来说没有意义
  • 使用 DataBindingComponent 的 Inflate 方法

    当 Glide 成功渲染图像后 我在更新文本视图时看到此错误 致命异常 java lang IllegalStateException 必需 CustomBinding 类中的 DataBindingComponent 为 null 绑定适
  • 异步多播委托

    我最近在一个广泛使用事件的项目上做了一些工作 我需要做的事情之一是在多播委托上异步调用多个事件处理程序 我认为诀窍是对 GetInvocableList 中的每个项目调用 BeginInvoke 但似乎那里不存在 BeginInvoke 有
  • ComboBox DataBinding 导致 ArgumentException

    我的几个类对象 class Person public string Name get set public string Sex get set public int Age get set public override string
  • JavaScript Promise 不执行 .then()

    我在 JavaScript 中的 Promise 方面遇到了一些问题 我想做的是获得一个地址列表 然后对于每个地址 我需要调用地理编码 API 来获取 lat lng 然后我将继续将标记与热图一起绘制 这是我的代码 let promiseK
  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • 使用 Xamarin Forms 显示图像

    Solved 答案是更新所有 nuget 软件包并针对较新版本的 Android 现在图像按预期加载 我对此并不满意 因为我完全使用了 Xamarin 提供的代码 并且针对较新的版本已弃用了代码所依赖的一些项目 初始版本是 Xamarin
  • C++ 异步线程同时运行

    我是 C 11 中线程的新手 我有两个线程 我想让它们同时启动 我可以想到两种方法 如下 然而 似乎它们都没有按照我的预期工作 他们在启动另一个线程之前启动一个线程 任何提示将不胜感激 另一个问题是我正在研究线程队列 所以我会有两个消费者和
  • 主线程迭代之间的资源锁定(Async/Await)

    假设我有一个带有两个按钮的表单 button1 and button2 和资源对象 r 资源有自己的锁定和解锁代码来处理并发性 任何线程都可以修改资源 When button1单击后 其处理程序会进行一些修改r本身然后调用 Independ
  • 将 React Native 集成到 Xamarin 项目中

    我的任务是看看是否可以将 React Native 集成到 Xamarin Forms 项目中 我认为我已经非常接近实现这一目标 但我不能肯定地说 我知道这是一个有点奇怪 倒退的解决方案 但无论如何我想尝试一下 看看我是否可以打败它 Int
  • 如何更改 WPF TabControl 的 ItemTemplate 的样式以便设置选项卡标题的背景颜色?

    我使用 WPF TabControl 的 ItemTemplate 属性来绑定每个 TabItem 标头的内容 我还使用 ItemContainerStyle 属性将 TabItem 的内容设置为动态选择的用户控件 此方法 100 按预期工
  • 使用路径=。和绑定内的转换器

    我无法为 TreeViewItems 定义触发器 我相信这只是一些语法问题 但我不知道还要写什么 这是触发器
  • Web UI 中的 .Result 出现死锁

    我正在阅读以下主题http blog stephencleary com 2012 07 dont block on async code html http blog stephencleary com 2012 07 dont bloc
  • 使用 Linq 进行异步Where过滤

    我有一个List通过填充的元素async调用 WebService 没问题 我需要过滤该列表以便在应用程序视图上显示某些内容 我试过这个 List
  • 如何使用Python3.4在tornado中进行异步mysql操作?

    我现在使用Python3 4 我想在Tornado中使用异步mysql客户端 我已经发现torndb https github com bdarnell torndb但在阅读其源代码后 我认为它无法进行异步mysql操作 因为它只是封装了M
  • 将“Android.Views.ViewGroup”添加到 Xamarin XAML 页面

    我需要一些帮助来添加Android Views ViewGroup到 XAML 页面 我有一个 Xamarin 项目 其解决方案结构如下所示 App1 ViewModels MyPageViewModel cs Views MyPageVi
  • 什么是 ng-template 以及为什么我要将 *ngIf then else 绑定到它?

    当我将 ngIf 与 then 和 或 else 语句一起使用时 为什么我必须绑定到附加到ng template元素 例如 这有效 div Text to show div
  • 使用数据绑定,如何将包含表情符号的文本绑定到标签并使其正确显示?

    我正在编写一个应用程序来连接 WordPress BuddyPress API 该应用程序将允许用户通过 API 相互发送消息 当这些消息包含表情符号时 我很难正确显示它们 以下是 API 返回的消息文本的简短示例 Hi x1f642 ho

随机推荐

  • 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