当前位置: 首页 > news >正文

ReactiveUI MVVM框架(1)-Collections

ReactiveUI MVVM框架(1)-Collections

ReactiveUI使用动态数据(DynamicData)用于集合的操作。

当对动态数据集合进行更改时,会产生更改通知,通知表示为ChangeSet,里面包含了更改信息,多个更改通知为IObservable<ChangeSet>。动态数据提供了两种特定的集合,分别是SourceCache<TObject, TKey>SourceList<T>。第一个为带key的字典式,也就是不能重复,第二个为集合式。如何要将这两种集合转换为IObservable<ChangeSet>,可以使用Connect方法。

需要注意的是,这跟WPF中常用的ObservableCollection<T>的实现方式是不同的。

简单使用

从wpf中常用的ObservableCollection<T>得到IObservable<ChangeSet>

// 'myList' is ObservableCollection<T>
// 'myDerivedList' is IObservableList<T>
var myDerivedList = myList.ToObservableChangeSet().Filter(t => t.Status == "Something").AsObservableList();// 'myList' is ObservableCollection<T>
// 'myDerivedCache' is IObservableCache<T, TKey>
var myDerivedCache = myList.ToObservableChangeSet(t => t.Id).Filter(t => t.Status == "Something").AsObservableCache();

以上两种方式是线程不安全的,加入myList绑定到了View上,那么在View上也可能对myList进行更改。推荐的方法是先创建一个数据源。

var myList = new SourceList<T>()
var disposable = myList.Connect() // 获得IObservable<ChangeSet>.\\some other operation

这种方法的好处是可以在后台线程上进行维护。比如:

//ReadOnlyObservableCollection可以多线程操作
ReadOnlyObservableCollection<T> bindingData;
var disposable = mySource.Connect() // make the source an observable change set.Sort(SortExpressionComparer<T>.Ascending(t => t.DateTime)).ObserveOn(RxApp.MainThreadScheduler) // 'mySource' 会在其他线程上更新.Bind(out bindingData).Subscribe(); 

ReactiveUI使用动态数据

开发时,会遇到可变集合和不可变集合,当对不可变集合进行处理时,简单情况下可以使用ObservableAsPropertyHelper<T>,它包含一个Observable<T>。每次给集合赋予新的集合时会触发通知事件。

而对于可变集合,往往采用动态数据的方式。

案例

public class Service 
{//定义一个数据集private readonly SourceList<bool> _items = new SourceList<bool>();//暴露给外面public IObservable<IChangeSet<bool>> Connect() => _items.Connect();public Service(){        _items.Add(true);_items.RemoveAt(0);_items.Add(false);}
}

ReadOnlyObservableCollection

  • 动态数据往往使用ReadOnlyObservableCollection<T>之类的类型对外公开,而不是它本身的类型。IObservable<IChangeSet<T>>IObservable<IChangeSet<TObject, TKey>>是可以观测类型,IObservable<IChangeSet<T>>中含有集合更改的内容,第一次使用ToObservableChangeSet()时会发出集合的当前状态。
  • SourceListSourceCache是可以使用多线程进行创建IObservable<IChangeSet<T>>等,通常SourceListSourceCache应该定义为Private,而是通过Connect方法暴露给View。
public class ViewModel : ReactiveObject
{private readonly ReadOnlyObservableCollection<bool> _items;public ReadOnlyObservableCollection<bool> Items => _items;public ViewModel(){var service = new Service();service.Connect()// Transform 和Select方法类似,只不过是观察一个集合的变化且将元素投影到另一个集合.Transform(x => !x)// Filter 类似于Where.Filter(x => x)// 确保更先到UI线程..ObserveOn(RxApp.MainThreadScheduler)// 通过 .Bind() 方法实现可变集合包含新的数据并且刷新UI.Bind(out _items).Subscribe();}
}

ObservableCollectionExtended

ObservableCollectionExtended<T>是一个单线程集合,如果要同步VM中的两个集合,可以将其中一个声明为ObservableCollectionExtended<T>,另一个声明为ReadOnlyObservableCollection<T>,然后使用.ToObservableChangeSet()方法将其转换为IObservable<IChangeSet<T>>

public class SynchronizedCollectionsViewModel : ReactiveObject
{private readonly ReadOnlyObservableCollection<bool> _derived;public ReadOnlyObservableCollection<bool> Derived => _derived;public ObservableCollectionExtended<bool> Source { get; }public SynchronizedCollectionsViewModel(){Source = new ObservableCollectionExtended<bool>();Source.ToObservableChangeSet().Transform(value => !value)// 在这里不需要使用ObserveOn更新UI线程,因为它是单线程.Bind(out _derived).Subscribe();Source.Add(true);Source.RemoveAt(0);Source.Add(false);Source.Add(true);}
}

根据集合中的更改

ReactiveObject类实现了INotifyPropertyChanged,动态数据可以对ReactiveObject类进行跟踪。

// 'collectionOfReactiveObjects' 是 ObservableCollection<T>
//  T inherits 继承自 ReactiveObject
// 'databasesValid' 则是 IObservable<bool>
var databasesValid = collectionOfReactiveObjects.ToObservableChangeSet().AutoRefresh(model => model.IsValid) // 订阅IsValid属性的更改.ToCollection()                      // 获取新项目集合.Select(x => x.All(y => y.IsValid)); // 验证是否满足条件.// 将IObservable<bool> 转为视图模型
// '_databasesValid' 是ObservableAsPropertyHelper<bool> 类型
_databasesValid = databasesValid.ToProperty(this, x => x.DatabasesValid);

ReactiveList转为动态数据

如果使用的是ReactiveList<T>,并且仅从UI线程添加/删除,则使用ObservableCollectionExtended<T>

相关文章:

ReactiveUI MVVM框架(1)-Collections

ReactiveUI MVVM框架&#xff08;1&#xff09;-Collections ReactiveUI使用动态数据&#xff08;DynamicData&#xff09;用于集合的操作。 当对动态数据集合进行更改时&#xff0c;会产生更改通知&#xff0c;通知表示为ChangeSet&#xff0c;里面包含了更改信息&#xff0…...

【微服务】五. Nacos服务注册

Nacos服务注册 5.1 Nacos服务分级存储模型Nacos服务分级存储模型&#xff1a;服务集群属性&#xff1a;总结&#xff1a; 5.2 根据集群负载均衡总结 5.3 Nacos服务实例的权重设置总结&#xff1a; 5.6 环境隔离namespace总结 5.7 Nacos和Eureka的对比总结 5.1 Nacos服务分级存储…...

Lnmp架构-Redis

网站&#xff1a;www.redis.cn redis 部署 make的时候需要gcc和make 如果在纯净的环境下需要执行此命令 [rootserver3 redis-6.2.4]# yum install make gcc -y 注释一下这几行 vim /etc/redis/6739.conf 2.Redis主从复制 设置 11 是master 12 13 是slave 在12 上 其他节…...

Python 二进制数据处理与转换

不得不说&#xff0c;Python能火是有原因的&#xff0c;物联网开发中常用的数据处理方式&#xff0c;Python都有内置的函数或方法&#xff0c;相当方便&#xff0c;官方文档见二进制序列类型&#xff0c;下面是一些示例代码 string Hello World! # 字符串转二进制数据 data …...

【LeetCode】297.二叉树的序列化与反序列化

题目 序列化是将一个数据结构或者对象转换为连续的比特位的操作&#xff0c;进而可以将转换后的数据存储在一个文件或者内存中&#xff0c;同时也可以通过网络传输到另一个计算机环境&#xff0c;采取相反方式重构得到原数据。 请设计一个算法来实现二叉树的序列化与反序列化…...

Java HashSet

HashSet 基于 HashMap 来实现的&#xff0c;是一个不允许有重复元素的集合。 HashSet 允许有 null 值。 HashSet 是无序的&#xff0c;即不会记录插入的顺序。 HashSet 不是线程安全的&#xff0c; 如果多个线程尝试同时修改 HashSet&#xff0c;则最终结果是不确定的。 您必…...

在iPhone上构建自定义数据采集完整指南

在iPhone上构建自定义数据采集工具可以帮助我们更好地满足特定需求&#xff0c;提高数据采集的灵活性和准确性。本文将为您提供一份完整的指南和示例代码&#xff0c;教您如何在iPhone上构建自定义数据采集工具。 自定义数据采集工具的核心组件 a、数据模型 数据模型是数据采…...

Android MediaRecorder录音

1. 简介 在android中录制音频有两种方式&#xff0c;MediaRecorder和AudioRecord。两者的区别如下&#xff1a; MediaRecorder 简单方便&#xff0c;不需要理会中间录制过程&#xff0c;结束录制后可以直接得到音频文件进行播放&#xff1b;录制的音频文件是经过压缩的&#…...

软件提示vcruntime140_1.dll丢失的解决方法,以及丢失的原因总结

在运行某些程序时&#xff0c;可能会出现“vcruntime140_1.dll 丢失”的错误提示。这是因为 vcruntime140_1.dll 是 Visual C Redistributable 的一部分&#xff0c;它通常被安装在 Windows 操作系统上。如果该文件丢失或无法找到&#xff0c;可能会导致程序无法正常运行。在我…...

Datax抽取mysql的bit类型数据

背景&#xff1a;使用datax抽取mysql的一张表&#xff0c;里面有两个bit类型的字段&#xff0c;抽取出来显示如下&#xff1a; 需要在抽取reader里面进行处理配置 最终生成的datax的json文件reader的配置会转换为具体的数值 最终查询效果&#xff1a;...

git 后悔药

前言 自上而下&#xff0c;撤销可以分为从远程库撤销&#xff0c;从本地库撤销&#xff0c;从暂存库撤销。 例子&#xff1a;代码已经提交了三个记录到远程库&#xff0c;分别对应了记录1&#xff0c;内容1&#xff0c;记录2&#xff0c;内容2&#xff0c;记录3&#xff0c;内…...

vue-cli搭建一个新项目及基础配置

vue-cli搭建一个新项目及基础配置 一、安装步骤二、main.js配置三、router下的index.js 一、安装步骤 1.安装node环境&#xff1a;下载地址&#xff1a;Node.js 2.安装脚手架&#xff1a;npm install -g vue/cli 3.创建vue项目&#xff1a;vue create 项目名 4.进入项目&…...

【C++】 C++11(右值引用,移动语义,bind,包装器,lambda,线程库)

文章目录 1. C11简介2. 统一的列表初始化2.1 &#xff5b;&#xff5d;初始化2.2 std::initializer_list 3. 声明3.1 auto3.2 decltype3.3 auto与decltype区别3.4 nullptr 4. 右值引用和移动语义4.1 左值引用和右值引用4.2 左值引用与右值引用比较4.3 右值引用使用场景和意义4.…...

附录1-爬虫的一些技巧

目录 1 寻找url与显示内容的关系 2 修改请求头 3 局部刷新 4 阅读返回信息 5 多尝试页面其他的使用方式 6 尝试不同类型参数 7 表单类型的post多用data发&#xff0c;接口类型的post多用json发 8 消除degger 9 你在浏览器上看到的html与你下载下来的html不一…...

【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】HAL移植

一、环境介绍 RK3588主板搭载Android12操作系统,内核是Linux5.10,使用ST的六轴传感器LSM6DSR芯片。 二、芯片介绍 LSM6DSR是一款加速度和角速度(陀螺仪)六轴传感器,还内置了一个温度传感器。该芯片可以选择I2C,SPI通讯,还有可编程终端,可以后置摄像头等设备,功能是很…...

DragGAN应运而生,未来在4G视频上都可能利用拖拽式编辑

原创 | 文 BFT机器人 2023年8月14日-15日&#xff0c;第七届GAIR全球人工智能与机器人大会在新加坡乌节大酒店成功举办。 在「AIGC 和生成式内容」分论坛上&#xff0c;南洋理工大学科学与工程学院助理教授潘新钢以《Interacitve Point-Dragging Manipulation of Visual Cont…...

【C++技能树】多态解析

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 文章目录 0.多态的概念0.1 多态的定义 1. 重写2.Final与Override3.抽象类4.多态中的内存分布.4.1虚表存在哪里? 5.多态调用原理5.1 动态绑定与静…...

【爬虫笔记】Python爬虫简单运用爬取代理IP

一、前言 近些年来&#xff0c;网络上的爬虫越来越多&#xff0c;很多网站都针对爬虫进行了限制&#xff0c;封禁了一些不规则的请求。为了实现正常的网络爬虫任务&#xff0c;爬虫常用代理IP来隐藏自己的真实IP&#xff0c;避免被服务器封禁。本文将介绍如何使用Python爬虫来…...

IP协议-NAT机制(理解网络结构的关键要点)

前言 我们现在使用得最多的IP协议版本是IPv4&#xff0c;IPv4是4个字节&#xff0c;32位&#xff0c;也就是说我们的IP地址最多就只有2^32&#xff08;42亿&#xff09;个&#xff0c;在日常生活中&#xff0c;我们需要联网的设备都需要有IP地址才能进行通讯&#xff0c;很明显…...

Python UI自动化 —— 关键字+excel表格数据驱动

步骤&#xff1a; 1. 对selenium进行二次封装&#xff0c;创建关键字的库 2. 准备一个表格文件来写入所有测试用例步骤 3. 对表格内容进行读取&#xff0c;使用映射关系来对用例进行调用执行 4. 执行用例 1. 对selenium进行二次封装&#xff0c;创建关键字的库 from time imp…...

用HSPICE玩转CMOS反相器:手把手教你分析尺寸、延迟与功耗的权衡

用HSPICE玩转CMOS反相器&#xff1a;手把手教你分析尺寸、延迟与功耗的权衡 在集成电路设计的浩瀚宇宙中&#xff0c;CMOS反相器就像是一颗不起眼却至关重要的基础星体。作为数字电路中最简单的构建模块&#xff0c;它的性能表现直接影响着整个系统的运行效率。对于已经掌握HS…...

使用Taotoken为Hermes Agent配置自定义模型提供方详细步骤

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 使用Taotoken为Hermes Agent配置自定义模型提供方详细步骤 对于使用Hermes Agent框架构建智能体应用的开发者而言&#xff0c;灵活…...

League Akari:英雄联盟玩家的智能游戏助手

League Akari&#xff1a;英雄联盟玩家的智能游戏助手 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power &#x1f680;. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 你是否厌倦了在英雄联盟中重复繁琐的准备…...

独立开发者如何利用TaotokenTokenPlan降低项目试错成本

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 独立开发者如何利用Taotoken TokenPlan降低项目试错成本 对于独立开发者或小型团队而言&#xff0c;启动一个涉及大模型能力的项目…...

Steam库存管理革命:5分钟掌握批量操作终极指南

Steam库存管理革命&#xff1a;5分钟掌握批量操作终极指南 【免费下载链接】Steam-Economy-Enhancer 中文版&#xff1a;Enhances the Steam Inventory and Steam Market. 项目地址: https://gitcode.com/gh_mirrors/ste/Steam-Economy-Enhancer Steam Economy Enhancer…...

如何用DS4Windows让PS4手柄在PC上完美运行?3步解锁专业游戏体验

如何用DS4Windows让PS4手柄在PC上完美运行&#xff1f;3步解锁专业游戏体验 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows 你是否曾经想过在PC上使用心爱的PS4手柄玩游戏&#xff0c;却发…...

用Gemini3.1Pro高效撰写工作汇报从素材整理到终稿交付全流程

做多模型横向对比测试时常用的聚合平台推荐下&#xff1a;库拉KULAAI&#xff08;c.877ai.cn&#xff09;&#xff0c;上面能直接调Gemini 3.1 Pro和多个主流模型做职场办公场景对比。下面进入正题。工作汇报和周报不是一回事很多人把工作汇报和周报混为一谈。周报是流水线上的…...

基于CircuitPython与GBoard的Android摩斯码输入外设制作指南

1. 项目概述与核心价值如果你对摩斯码感兴趣&#xff0c;或者身边有朋友因为行动不便&#xff0c;使用传统触摸屏键盘输入文字非常困难&#xff0c;那么这个项目可能会给你带来一些全新的思路。我们这次要做的&#xff0c;不是一个复杂的、需要焊接和精密加工的电子项目&#x…...

Live Server 5分钟完全指南:如何在VSCode中实现浏览器实时预览?

Live Server 5分钟完全指南&#xff1a;如何在VSCode中实现浏览器实时预览&#xff1f; 【免费下载链接】vscode-live-server Launch a development local Server with live reload feature for static & dynamic pages. 项目地址: https://gitcode.com/gh_mirrors/vs/vs…...

绝区零自动化终极指南:如何用一条龙工具实现全自动游戏体验

绝区零自动化终极指南&#xff1a;如何用一条龙工具实现全自动游戏体验 【免费下载链接】ZenlessZoneZero-OneDragon 绝区零 一条龙 | 全自动 | 自动闪避 | 自动每日 | 自动空洞 | 支持手柄 项目地址: https://gitcode.com/gh_mirrors/ze/ZenlessZoneZero-OneDragon 还在…...