亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

WPF運(yùn)行時(shí)替換方法實(shí)現(xiàn)mvvm自動(dòng)觸發(fā)刷新

 更新時(shí)間:2024年04月30日 08:59:48   作者:CodeOfCC  
這篇文章主要為大家詳細(xì)介紹了WPF運(yùn)行時(shí)如何實(shí)現(xiàn)setter不需要調(diào)方法就可以自動(dòng)觸發(fā)界面刷新,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

我們知道,使用wpf的綁定功能,代碼觸發(fā)界面改變時(shí)需要在屬性的setter觸發(fā)PropertyChanged事件,以達(dá)到界面刷新的效果。上一章我們簡(jiǎn)化了觸發(fā)流程,但是依然需要在每個(gè)屬性的setter中調(diào)用方法。本章將再進(jìn)一步簡(jiǎn)化,實(shí)現(xiàn)setter不需要調(diào)方法就可以自動(dòng)觸發(fā)界面刷新。

一、如何實(shí)現(xiàn)

1、反射獲取屬性

通過(guò)反射獲取類的所有公有屬性

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

2、定義替換方法

定義的用于替換屬性setter的方法,確保參數(shù)類型兼容。設(shè)置NoInlining確保不會(huì)被內(nèi)聯(lián)優(yōu)化失去函數(shù)地址。再方法中觸發(fā)RaisePropertyChangedEvent。

 [MethodImpl(MethodImplOptions.NoInlining)] 
 void Setter0_obj(object value) { 
  //此時(shí)Setter0_obj已經(jīng)被替換成了屬性的setter,調(diào)用會(huì)進(jìn)入屬性的setter中。
  Setter0_obj(value);
  RaisePropertyChangedEvent(_propertyInfos![0].Name); }

3、交換屬性的setter方法

將定義的替換方法與屬性的setter交換。MethodHooker.SwapMethod可以去搜索C#運(yùn)行時(shí)替換函數(shù)的方法,本章的只是去掉了unsafe的實(shí)現(xiàn)。

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

二、完整代碼

1、接口

/// <summary>
/// ViewModelBase,繼承此類可以簡(jiǎn)化屬性的定義,不需要手動(dòng)觸發(fā)RaisePropertyChangedEvent。
/// 用法:繼承此類,屬性為公有,set為公有且非內(nèi)聯(lián),設(shè)置屬性就會(huì)自動(dòng)觸發(fā)mvvm的binding。
/// 實(shí)驗(yàn)性質(zhì),其他.net版本無(wú)效,在.net6.0是穩(wěn)定的,。x64、x86,debug和release都可以使用。release需要給set設(shè)置[MethodImpl(MethodImplOptions.NoInlining)],否則無(wú)法實(shí)現(xiàn)函數(shù)交換。
/// 目前支持64個(gè)屬性,單個(gè)屬性(struct)最大128字節(jié),需要更多可以自行調(diào)用GenSetters生成代碼。
/// </summary>
public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public ViewModelBase();
    //依然提供此方法用于手動(dòng)觸發(fā)
    protected void RaisePropertyChangedEvent([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "");
}

2、項(xiàng)目

vs2022 .net 6.0項(xiàng)目。

注:目前版本只能在.net6.0中正常使用,x64、x86、debug、release都沒問(wèn)題。其他.net版本大概率無(wú)效果或者異常。

三、使用示例

倒計(jì)時(shí)

(1)繼承ViewModelBase

public class TimeTick : ViewModelBase

(2)定義屬性

set為公有,以及[MethodImpl(MethodImplOptions.NoInlining)]避免內(nèi)聯(lián)。支持非缺省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)窗口關(guān)聯(lián)ViewModel

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

(5)xaml綁定

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

效果預(yù)覽

總結(jié)

替換函數(shù)原理很簡(jiǎn)單,但是具體實(shí)現(xiàn)還是比較麻煩的,尤其是需要適配不同的.net版本,本文目前只支持.net6.0。還有就是函數(shù)的參數(shù),引用和值類型的區(qū)分,以及值類型的傳值兼容,這些都是通過(guò)多次嘗試才找個(gè)合理的方式。通過(guò)本文簡(jiǎn)化的ViewModelBase使用變的非常方便了,除了需要給set添加非內(nèi)聯(lián)屬性,其他已經(jīng)和普通屬性沒有區(qū)別。

到此這篇關(guān)于WPF運(yùn)行時(shí)替換方法實(shí)現(xiàn)mvvm自動(dòng)觸發(fā)刷新的文章就介紹到這了,更多相關(guān)WPF mvvm自動(dòng)觸發(fā)刷新內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Unity實(shí)現(xiàn)局域網(wǎng)聊天室功能

    Unity實(shí)現(xiàn)局域網(wǎng)聊天室功能

    這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)局域網(wǎng)聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C#圖形編程GDI+基礎(chǔ)介紹

    C#圖形編程GDI+基礎(chǔ)介紹

    這篇文章介紹了C#中的圖形編程GDI+,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • C#利用OpenCvSharp實(shí)現(xiàn)玉米粒計(jì)數(shù)

    C#利用OpenCvSharp實(shí)現(xiàn)玉米粒計(jì)數(shù)

    這篇文章主要為大家詳細(xì)介紹了C#如何結(jié)合OpenCVSharp4實(shí)現(xiàn)玉米粒計(jì)數(shù),文中的示例代碼簡(jiǎn)潔易懂,具有一定的學(xué)習(xí)價(jià)值,需要的小伙伴可以參考下
    2023-11-11
  • C#通過(guò)不安全代碼看內(nèi)存加載的示例詳解

    C#通過(guò)不安全代碼看內(nèi)存加載的示例詳解

    C#中類型分為值類型和引用類型。這篇文章將用不安全代碼的地址,來(lái)看一下值類型和引用類型的存儲(chǔ),文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-07-07
  • C#實(shí)現(xiàn)用棧求逆序的方法示例

    C#實(shí)現(xiàn)用棧求逆序的方法示例

    這篇文章主要介紹了C#實(shí)現(xiàn)用棧求逆序的方法,涉及C#數(shù)據(jù)結(jié)構(gòu)中棧的壓入與取出相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07
  • C#使用Monitor類實(shí)現(xiàn)線程同步

    C#使用Monitor類實(shí)現(xiàn)線程同步

    這篇文章介紹了C#使用Monitor類實(shí)現(xiàn)線程同步的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C#中深度復(fù)制和淺度復(fù)制詳解

    C#中深度復(fù)制和淺度復(fù)制詳解

    這篇文章主要介紹了C#中深度復(fù)制和淺度復(fù)制的相關(guān)資料,需要的朋友可以參考下
    2015-10-10
  • C#實(shí)現(xiàn)排列組合算法完整實(shí)例

    C#實(shí)現(xiàn)排列組合算法完整實(shí)例

    這篇文章主要介紹了C#實(shí)現(xiàn)排列組合算法的完整實(shí)例,文中實(shí)例主要展示了排列循環(huán)方法和排列堆棧方法,需要的朋友可以參考下
    2014-09-09
  • C#生成word記錄實(shí)例解析

    C#生成word記錄實(shí)例解析

    這篇文章主要介紹了C#生成word記錄實(shí)例解析,很實(shí)用的功能,需要的朋友可以參考下
    2014-08-08
  • C#實(shí)現(xiàn)身份證號(hào)碼驗(yàn)證的方法

    C#實(shí)現(xiàn)身份證號(hào)碼驗(yàn)證的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)身份證號(hào)碼驗(yàn)證的方法,通過(guò)封裝的類文件實(shí)例化調(diào)用實(shí)現(xiàn)了對(duì)身份證號(hào)碼的驗(yàn)證,是非常實(shí)用的技巧,需要的朋友可以參考下
    2014-11-11

最新評(píng)論