C# wpf 运行时替换方法实现mvvm自动触发刷新

news2024/11/24 15:56:16

文章目录

  • 前言
  • 一、如何实现?
    • 1、反射获取属性
    • 2、定义替换方法
    • 3、交换属性的setter方法
  • 二、完整代码
    • 1、接口
    • 2、项目
  • 三、使用示例
    • 1、倒计时
      • (1)、继承ViewModelBase
      • (2)、定义属性
      • (3)、属性赋值
      • (4)、窗口关联ViewModel
      • (5)、xaml绑定
  • 总结


前言

我们知道,使用wpf的绑定功能,代码触发界面改变时需要在属性的setter触发PropertyChanged事件,以达到界面刷新的效果。上一章我们简化了触发流程,但是依然需要在每个属性的setter中调用方法。本章将再进一步简化,实现setter不需要调方法就可以自动触发界面刷新


一、如何实现?

1、反射获取属性

通过反射获取类的所有公有属性

var propertyInfos = type.GetProperties(bindingAttr: BindingFlags.Instance | BindingFlags.Public);

2、定义替换方法

定义的用于替换属性setter的方法,确保参数类型兼容。设置NoInlining确保不会被内联优化失去函数地址。再方法中触发RaisePropertyChangedEvent。

 [MethodImpl(MethodImplOptions.NoInlining)] 
 void Setter0_obj(object value) { 
  //此时Setter0_obj已经被替换成了属性的setter,调用会进入属性的setter中。
  Setter0_obj(value);
  RaisePropertyChangedEvent(_propertyInfos![0].Name); }

3、交换属性的setter方法

将定义的替换方法与属性的setter交换。MethodHooker.SwapMethod可以去搜索C#运行时替换函数的方法,本章的只是去掉了unsafe的实现。

var oldSetter = propertyInfos[i].GetSetMethod();
if (oldSetter != null && oldSetter.IsPublic)
//定义了set且set为公有时才交换。
{
    MethodInfo newSetter= type.BaseType.GetMethod("Setter0_obj", BindingFlags.Instance | BindingFlags.NonPublic)!;
    MethodHooker.SwapMethod(oldSetter, newSetter);
}

二、完整代码

1、接口

/// <summary>
/// ViewModelBase,继承此类可以简化属性的定义,不需要手动触发RaisePropertyChangedEvent。
/// 用法:继承此类,属性为公有,set为公有且非内联,设置属性就会自动触发mvvm的binding。
/// 实验性质,其他.net版本无效,在.net6.0是稳定的,。x64、x86,debug和release都可以使用。release需要给set设置[MethodImpl(MethodImplOptions.NoInlining)],否则无法实现函数交换。
/// 目前支持64个属性,单个属性(struct)最大128字节,需要更多可以自行调用GenSetters生成代码。
/// </summary>
public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public ViewModelBase();
    //依然提供此方法用于手动触发
    protected void RaisePropertyChangedEvent([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "");
}

2、项目

vs2022 .net 6.0项目。
https://download.csdn.net/download/u013113678/89241921
注:目前版本只能在.net6.0中正常使用,x64、x86、debug、release都没问题。其他.net版本大概率无效果或者异常。属于实验性质,请根据需要下载。


三、使用示例

1、倒计时

(1)、继承ViewModelBase

public class TimeTick : ViewModelBase

(2)、定义属性

set为公有,以及[MethodImpl(MethodImplOptions.NoInlining)]避免内联。支持非缺省set方法体,即可以在set中加入一些逻辑。

public class TimeTick : ViewModelBase
{
    public double Seconds { get; [MethodImpl(MethodImplOptions.NoInlining)] set; }=60;
}

(3)、属性赋值

public TimeTick()
{
    var time = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(1000) };
    time.Tick += (s, e) =>Seconds--;     
    time.Start();
}

(4)、窗口关联ViewModel

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new TimeTick();
    }
}

(5)、xaml绑定

 <TextBlock Text="{Binding Seconds}" />

效果预览
在这里插入图片描述


总结

以上就是今天讲述的内容,替换函数原理很简单,但是具体实现还是比较麻烦的,尤其是需要适配不同的.net版本,本文目前只支持.net6.0。还有就是函数的参数,引用和值类型的区分,以及值类型的传值兼容,这些都是通过多次尝试才找个合理的方式。通过本文简化的ViewModelBase使用变的非常方便了,除了需要给set添加非内联属性,其他已经和普通属性没有区别。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1634069.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Redis 开发】Lua语言

Lua Lua语法 Lua语法 Lua是一种小巧的脚本语言&#xff0c;底层用C语言实现&#xff0c;为了嵌入式应用程序中 官网&#xff1a;https://www.lua.org/ 创建lua文件 touch hello.lua 运行lua文件 lua hello.lua 输出语句 print("Hello World!")数据类型 可以通过t…

python与上位机开发day04

模块和包、异常、PyQt5 一、模块和包 1.1 模块 Python中模块就是一个.py文件&#xff0c;模块中可以定义函数&#xff0c;变量&#xff0c;类。模块可以被其他模块引用 1.1.1 导入模块 """ 导入格式1&#xff1a; import 模块名 使用格式&#xff1a; …

【算法基础实验】图论-最小生成树Prim的延迟实现

最小生成树-Prim的延迟实现 理论基础 树的基本性质 用一条边连接树中的任意两个顶点都会产生一个新的环&#xff1b; 从树中删去一条边将会得到两棵独立的树。 切分定理的定义 定义。图的一种切分是将图的所有顶点分为两个非空且不重叠的两个集合。横切边 是一条连接两个属…

认识认识DHCP

文章目录 认识认识DHCP一、什么是DHCP&#xff1f;1.1、为什么要使用DHCP&#xff1f;1.2、DHCP是怎么工作的&#xff1f;1.2.1、客户端首次接入网络的工作原理1.2.2、客户端重用曾经使用过的地址的工作原理1.2.3、客户端更新租期的工作原理 二、配置DHCP Server&#xff0c;为…

嵌入式开发二:搭建开发环境

工欲善其事必先利其器&#xff0c;本节我们从嵌入式开发的搭建环境开始学习&#xff0c;掌握最基本的搭建环境技能&#xff0c;了解每一部分的作用&#xff0c;以及如何使用是关键所在&#xff01; 目录 一、常用开发工具简介 二、如何安装KEIL5(MDK) 2.1认识MDK-ARM 2.2 …

Spring基于AspectJ实现验签切点

文章目录 引言I AspectJ 依赖II 验签切点2.1 匹配方法执行的连接点2.2 设置带有CustomAnnotation注解的方法为切点III 案例:验签2.1 用法2.2 定义注解2.3 定义切面和切点引言 需求:验签 实现:基于AspectJ实现验签切点 I AspectJ 依赖 AspectJ 是一个基于 Java 语言的 AOP …

windos蓝屏分析工具

BlueScreenView中文版 - Windows蓝屏分析工具 BlueScreenView中文版是一款非常方便的蓝屏诊断工具。它可以帮助您快速定位蓝屏问题&#xff0c;并提供详细的故障转储信息。该软件可以自动扫描您机器上的minidump文件夹&#xff0c;同时还支持根据路径查找蓝屏文件。 windos发…

Coursera: An Introduction to American Law 学习笔记 Week 06: Civil Procedure (完结)

An Introduction to American Law Course Certificate Course Introduction 本文是 https://www.coursera.org/programs/career-training-for-nevadans-k7yhc/learn/american-law 这门课的学习笔记。 文章目录 An Introduction to American LawInstructors Week 06: Civil Pro…

Flink checkpoint 源码分析

序言 最近因为工作需要在阅读flink checkpoint处理机制&#xff0c;学习的过程中记录下来&#xff0c;并分享给大家。也算是学习并记录。 目前公司使用的flink版本为1.11。因此以下的分析都是基于1.11版本来的。 在分享前可以简单对flink checkpoint机制做一个大致的了解。 …

docker学习笔记3:VmWare CentOS7安装与静态ip配置

文章目录 一、安装CentOS71、下载centos镜像2、安装二、设置静态ip三、xshell连接centos本专栏的docker环境是在centos7里安装,因此首先需要会安装centos虚拟机。 本篇博客介绍如何在vm虚拟机里安装centos7。 一、安装CentOS7 1、下载centos镜像 推荐清华源,下载如下版本 …

【C++】学习笔记——string_1

文章目录 四、模板初阶2. 类模板 五、STL简介1. 什么是STL2. STL的六大组件3. 如何学习STL 六、string类1. string类对象的容量操作 未完待续 四、模板初阶 2. 类模板 函数模板就是&#xff1a;模板 函数&#xff1b;类模板就是&#xff1a;模板 类。和函数模板用法基本相同…

Kafka客户端工具:Offset Explorer 使用指南

Kafka作为一个分布式流处理平台&#xff0c;在大数据处理和实时数据流应用中扮演着至关重要的角色。管理Kafka的topics及其offsets对于维护系统稳定性和数据一致性至关重要。Offset Explorer是一个强大的桌面应用程序&#xff0c;它使得管理和监控Kafka集群变得简单直观。本文将…

数组 Leetcode 704 二分查找/Leetcode 59 螺旋矩阵/Leetcode 203移除链表元素

数组 Leetcode 704 二分查找 Leetcode 704 学习记录自代码随想录 二分法模板记忆&#xff0c;数值分析中牛顿迭代法 class Solution { public:int search(vector<int>& nums, int target) {int left 0, right nums.size()-1;// 是否需要等于号&#xff0c;假设…

verilog分析task的接口设计,证明这种写法:assign {a,b,c,d} = links;

verilog分析task的接口设计&#xff0c;证明这种写法&#xff1a;assign {a,b,c,d} links; 1&#xff0c;task在状态机中的使用好处&#xff1a;2&#xff0c;RTL设计3&#xff0c;测试testbench4&#xff0c;波形分析&#xff0c;正确&#xff01; 参考文献&#xff1a; 1&am…

C++初阶学习第四弹——类与对象(中)——刨析类与对象的核心点

类与对象&#xff08;上&#xff09;&#xff1a;C初阶学习第三弹——类与对象&#xff08;上&#xff09;——初始类与对象-CSDN博客 前言&#xff1a; 在前面文章中&#xff0c;我们已经讲了类与对象的思想和类与对象的一些基本操作&#xff0c;接下来这篇文章我们将讲解以下…

NLP(10)--TFIDF优劣势及其应用Demo

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 TF*IDF&#xff1a; 优势&#xff1a; 可解释性好 可以清晰地看到关键词 即使预测结果出错&#xff0c;也很容易找到原因 计算速度快 分词本身占耗时最多&#xff0c;其余为简单统计计算 对标注数据依赖小 可以使用无标注语…

超级数据查看器 app v2.0发布 欢迎下载使用

超级数据查看器 app v2.0发布 欢迎下载使用 感谢大家的支持 &#xff1a;&#xff09; 点击访问APP下载界面 跳转 腾讯应用宝 简介 超级数据查看器软件&#xff08;简称超级数据查看器&#xff09;是一个提供数据查询和数据管理的手机APP&#xff0c;能导入文本数据&…

ubuntu neo4j 下载与配置(一)

neo4j 官方下载页面 https://neo4j.com/deployment-center/#community 进入页面之后&#xff0c;往下滑 咱们在下载neo4j时&#xff0c;官方可能要咱们填写一下个人信息&#xff0c;比如&#xff1a;姓名组织结构邮箱等&#xff1a; 咱们可以观察一下&#xff0c;ne4j的下载链…

大数据学习笔记14-Hive基础2

一、数据字段类型 数据类型 &#xff1a;LanguageManual Types - Apache Hive - Apache Software Foundation 基本数据类型 数值相关类型 整数 tinyint smallint int bigint 小数 float double decimal 精度最高 日期类型 date 日期 timestamps 日期时间 字符串类型 s…

OpenAI 新推出 AI 问答搜索引擎——SearchGPT 震撼登场

您的浏览器不支持 video 标签。 OpenAI-SearchGPT 近日&#xff0c;OpenAI 曝光了自己的一款令人瞩目的 AI 问答搜索引擎——SearchGPT。这款搜索引擎带来了全新的搜索体验&#xff0c;给整个行业带来了巨大的压力。 SearchGPT 支持多种强大的功能。首先&#xff0c;它能够通过…