当前位置: 首页 > 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…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

DiscuzX3.5发帖json api

参考文章&#xff1a;PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下&#xff0c;适配我自己的需求 有一个站点存在多个采集站&#xff0c;我想通过主站拿标题&#xff0c;采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题&#xff0c;进而引发后续程序异常。使用工具进行标准化操作&#xff0c;能有效降低出错概率。 需要快速整理大量文件的技术用户而言&#xff0c;这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB&#xff0c;…...

Python第七周作业

Python第七周作业 文章目录 Python第七周作业 1.使用open以只读模式打开文件data.txt&#xff0c;并逐行打印内容 2.使用pathlib模块获取当前脚本的绝对路径&#xff0c;并创建logs目录&#xff08;若不存在&#xff09; 3.递归遍历目录data&#xff0c;输出所有.csv文件的路径…...