MvvmLight入门教程

简介: MvvmLight是一款应用广泛的MVVM框架

MvvmLight

MvvmLight主要程序库

ViewModelLocator

在.netFramework环境下nuget安装MvvmLight会自动安装依赖项MvvmLightLibs库,如果在.net core环境下需要手动安装MvvmLightLibs库。

.netFramework环境下安装完成后,在ViewModel目录下具有一个ViewModelLocator类,该类的作用是提供依赖注入容器和相关属性。

publicclassViewModelLocator

{

   publicViewModelLocator()

   {

       ServiceLocator.SetLocatorProvider(() =>SimpleIoc.Default);

       //判断是否为设计时

       //if (ViewModelBase.IsInDesignModeStatic)

       SimpleIoc.Default.Register<MainViewModel>();//注册MainViewModel

       SimpleIoc.Default.Register<SubWindowVM>();//注册SubWindowVM

   }

   publicMainViewModelMain

   {

       get

       {   //返回MainViewModel实例,必须在前面进行注册后才可以

           returnServiceLocator.Current.GetInstance<MainViewModel>();

       }

   }

   publicSubWindowVMSubWin

   {

       get

       {

           returnServiceLocator.Current.GetInstance<SubWindowVM>();

       }

   }

   publicstaticvoidCleanup(){}

}

另外,在App.xaml中增加ViewModelLocator资源

<Application.Resources>

   <ResourceDictionary>

       <vm:ViewModelLocator  x:Key="Locator"/>

   </ResourceDictionary>

</Application.Resources>

这样在MainWindow中就可以这样注册DataContext

<WindowDataContext="{Binding Source={StaticResource Locator}, Path=Main}">

ObservableObject

ObservableObject继承了INotifyPropertyChanged,主要是简化了属性改变事件的触发

publicclassMainModel : ObservableObject

{

   privateintmyVar;

   publicintMyProperty

   {

       get { returnmyVar; }

       set

       {

           Set(refmyVar, value);

       }

   }

   privateint_value;

   publicintValue

   {

       get { return_value; }

       set {

           _value=value;

           RaisePropertyChanged("Value");

       }

   }

}

ViewModelBase

ViewModelBase继承了ObservableObjectIcleanup接口,自定义的ViewModel可以自己选择是否要继承ViewModelBase,该类中IsInDesignMode可以用来判断是否属于设计状态中。该类中另一常用的方法是Cleanup虚方法,用于进行资源释放。

资源释放

有时在某个VM中开启一个线程,当关闭View时,对应的VM中的线程仍然不会释放,此时就需要对VM中的线程资源进行释放。

publicclassSubWindowVM : ViewModelBase

{

   boolflag=true;

   privateintmyVar;

   publicintMyProperty

   {

       get { returnmyVar; }

       set { Set(refmyVar, value); }//效果相同

       //set { myVar = value; RaisePropertyChanged(); }

   }

   publicSubWindowVM()

   {

       Task.Run(() =>

       {

           inta=0;

           while (flag)

           {

               Debug.WriteLine($"=========={a++}=========");

               Task.Delay(1000).Wait();

           }

       });

   }

   //需要明确调用

   //释放VM中的资源,如线程,如果不调用,线程无法停止

   //瞬时模式,每次调用后需要清理

   publicoverridevoidCleanup()

   {

       base.Cleanup();

       flag=false;

   }

}

MvvmLight框架不会自动调用Cleanup方法,需要手动调用。比如当窗体关闭的时候,调用Cleanup方法,当时在View中直接调用VM中的方法违反了MVVM原则。不过,可以利用ViewModelLocator中的静态的Cleanup进行统一的资源释放。

ViewModelLocator中定义Cleanup的泛型方法

publicstaticvoidCleanup<T>() whereT:ViewModelBase

{

   ServiceLocator.Current.GetInstance<T>().Cleanup();//释放资源

   SimpleIoc.Default.Unregister<T>();//释放对象

   SimpleIoc.Default.Register<T>();//为下次打开可以用

}

这样在window的Closed事件中,可以直接调用ViewModelLocator中的Cleanup方法

privatevoidWindow_Closed(objectsender, EventArgse)

{

   ViewModelLocator.Cleanup<SubWindowVM>();

}

RelayCommand

RelayCommand继承自ICommand,用法和RouteCommand类似

publicICommandBtnCommand

{

   //get => new RelayCommand(() => { });

   //带参数

   get=>newRelayCommand<string>(obj=>

   { });

   //如果泛型定义为int则会转换失效,这里的泛型一般是引用,不能是值类型,因为用的反射机制

}

//任意事件的处理

publicICommandMouseCommand

{

   get=>newRelayCommand<object>(obj=>

   { });

}

Messenger

常规使用

Messenger使用非常灵活,可以在VM中出发,在View中执行逻辑。

在VM中发送

Messenger.Default.Send<int>(123);//广播方式

在View中注册

Messenger.Default.Register<int>(this,ReceiveMsg1);//广播方式

privatevoidReceiveMsg1(intmsg){}

如果不想以广播的方式进行发送,可以使用指定token的方式

  • 发送Messenger.Default.Send<int>(123, "M1");//指定Token
  • 注册Messenger.Default.Register<int>(this,"M1",ReceiveMsg2);//指定token

现在有如下需求,要在VM中触发,需要打开一个子窗口,并且还要得到子窗口是否打开的返回值。基于MVVM思想,子窗口属于View层,主窗口才能调用。

  • 新建一个类MessageAction

publicclassMessageAction<TValue,MResult>

{

    publicTValuevalue { set; get; }

    publicAction<MResult>State { set; get; }

    publicMessageAction(Action<MResult>state)

    {

        State=state;

    }

}

  • MainWindow

MessageAction<string, bool>ma=newMessageAction<string, bool>(GetReturn);

ma.value="123";

Messenger.Default.Send<MessageAction<string, bool>>(ma);

//可以得到返回值

privatevoidGetReturn(boolb)

{

}

  • MainViewModel

Messenger.Default.Register<MessageAction<string,bool>>(this, ReceiveMsg);

privatevoidReceiveMsg(MessageAction<string,bool>msg)

{

   bools=  newSubWindow().ShowDialog() ==true;//此时需要得到ShowDialog的返回值,true、false

   //使用委托来实现返回值给发送消息者

   stringss=msg.value;

   msg.State.Invoke(s);

   //为什么这样做,因为动作的触发点在VM中,VM中做触发的时候需要进行状态判断,也就是需要有返回值

   //需要View中进行窗口操作,并且返回状态

}

NotificationMessage

发送一个字符串给接受者

//触发

NotificationMessagenm=newNotificationMessage("hello");

Messenger.Default.Send<NotificationMessage>(nm);

//注册

Messenger.Default.Register<NotificationMessage>(this, ReceiveNM);

PropertyChangedMessage

传递一个字符串属性名和值发送给接收者,用于将PropertyChanged事件传播给收件人。

privatestring_value;

publicstringValue

{

   get { return_value; }

   set

   {

       _value=value;

       //有两种方式发送PropertyChangedMessage

       //1.broadcast:true

       Set(ref_value, value,broadcast:true);

       //2.Messenger.Default.Send

       PropertyChangedMessage<string>ddd=newPropertyChangedMessage<string>(Value, _value, "Value");

       Messenger.Default.Send<PropertyChangedMessage<string>>(ddd);

       //3.使用Broadcast

       Broadcast<string>(Value, _value, "Value")

   }

}

DispatcherHelper

//多线程,先检查是否在UI线程,如果不在则把该线程挂上去

//不能直接使用,需要配套

DispatcherHelper.Initialize();//一般把这一句写在App对象中

DispatcherHelper.CheckBeginInvokeOnUI()//异步的

//这样也可以

Application.Current.Dispatcher.Invoke()

相关文章
|
前端开发 C# 设计模式
利刃 MVVMLight 1:MVVMLight介绍以及在项目中的使用
原文:利刃 MVVMLight 1:MVVMLight介绍以及在项目中的使用 一、MVVM 和 MVVMLight介绍 MVVM是Model-View-ViewModel的简写。类似于目前比较流行的MVC、MVP设计模式,主要目的是为了分离视图(View)和模型(Model)的耦合。
2040 0
|
开发框架 .NET API
C#/.NET/.NET Core推荐学习书籍(24年8月更新)
C#/.NET/.NET Core推荐学习书籍(24年8月更新)
813 0
|
虚拟化
VMware Workstation产品常用的快捷键
文章介绍了VMware Workstation产品中常用的快捷键及其功能,包括对虚拟机的控制、设置、快照管理等操作,同时提供了作者的联系方式和博客链接。
1814 15
|
前端开发
前端常用方法防抖(debounce)和节流(throttle)的示例演示及应用场景说明
前端常用方法防抖(debounce)和节流(throttle)的示例演示及应用场景说明
857 0
|
机器学习/深度学习 人工智能 算法
GitHub星标破千!斯坦福大学的284个机器学习小抄(漫画中文版)
说到人工智能必然要了解机器学习,从信息化软件,到电子商务,然后到高速发展互联网时代,到至今的云计算、大数据等,渗透到我们的生活、工作之中,在互联网的驱动下,人们更清晰的认识和使用数据,不仅仅是数据统计、分析,我们还强调数据挖掘、预测。 机器学习就是对计算机一部分数据进行学习,然后对另外一些数据进行预测与判断。 机器学习的核心是”使用算法解析数据,从中学习,然后对新数据作出决定或预测”。也就是说计算机利用已获取的数据得出某一模型,然后利用此模型进行预测的一种方法,这个过程跟人的学习过程有些类似,比如人获取一定的经验,可以对新问题进行预测。
|
测试技术 持续交付 开发工具
一文掌握:Gitlab的完整使用手册
一文掌握:Gitlab的完整使用手册
|
开发框架 数据可视化 C#
C# | 上位机开发新手指南(三)框架
在上位机开发中,Windows Forms是使用最广泛的C#框架之一。Windows Forms是.NET Framework中的一个GUI框架,提供了丰富的GUI控件和易于使用的编程模型,可以快速开发Windows桌面应用程序。Windows Forms已经存在多年,并且在.NET Framework中得到广泛的支持和优化,因此在上位机开发中得到了广泛应用。除此之外,随着.NET Core的不断发展,越来越多的开发人员开始使用跨平台的C#框架进行上位机开发,例如使用Electron或Avalonia等框架开发基于Web技术的桌面应用程序。
1312 0
C# | 上位机开发新手指南(三)框架
|
Kubernetes 网络协议 Cloud Native
【直播回放】DeepFlow AutoLogging:自动采集应用调用日志和流日志
第九期“原力释放 云原生可观测性分享会”云杉网络 产品专家 李倩分享了《DeepFlow AutoLogging:自动采集应用调用日志和流日志》主题, DeepFlow AutoLogging 可以自动采集网络流日志,并提供丰富的性能指标和精细至每包的TCP时序日志,与应用调用日志结合提供完整的全栈回溯能力。
811 0
【直播回放】DeepFlow AutoLogging:自动采集应用调用日志和流日志
|
开发框架 弹性计算 运维
阿里云无影研发负责人任晋奎:无影核心技术能力突破
无影架构云网端融合体验背后的核心技术能力解读
1185 0
阿里云无影研发负责人任晋奎:无影核心技术能力突破

热门文章

最新文章