CommunityToolkit.Mvvm8.1 viewmodel源生成器写法(3)

 

本系列文章导航
  1. https://www.cnblogs.com/aierong/p/17300066.html
  2. https://github.com/aierong/WpfDemo (自我Demo地址)

希望提到的知识对您有所提示,同时欢迎交流和指正
作者:aierong
出处:https://www.cnblogs.com/aierong

 

说明

CommunityToolkit.Mvvm8.1最令人惊喜的是它提供的源生成器功能,它极大简化我们的mvvm代码
我们通过标记一个属性就可以实现某个功能,这个很方便快捷,推荐

常用标记总结
1.继承ObservableObject 并且类标记是分部类partial
2.私有变量标记属性 [ObservableProperty]
3.NotifyCanExecuteChangedFor  通知依赖命令
  NotifyPropertyChangedFor    通知依赖属性
4.RelayCommand  定义命令
5.OnPropertyChanged 手动通知属性更新
6.ButtonClickCommand.NotifyCanExecuteChanged() 手动通知命令更新
7.OnLastNameChanging OnLastNameChanged  某个属性改变
8.OnPropertyChanged  所有属性改变

 

定义viewmodel

定义vm时,请使用分部类,并且继承ObservableObject

public partial class DataViewModel2 : ObservableObject
{

}

 

ObservableProperty标记属性

定义属性如此简单:一个[ObservableProperty]标记搞定

/*
[ObservableProperty]标记后,会自动生成属性(大写命名),例如:下面会自动生成Title

注意:这个私有变量命名:必须是小写开头,或者下划线,或者m_
*/

[ObservableProperty]
private string title = "hello";

//public string Title
//{
//    get
//    {
//        return title;
//    }
//    set
//    {
//        //title = value;
//        //PropertyChanged?.Invoke( this , new PropertyChangedEventArgs( "Name" ) );

//        //SetProperty 相当与设置值,并且PropertyChanged通知调用
//        SetProperty( ref title , value );
//    }
//}

 

NotifyPropertyChangedFor通知依赖属性

[NotifyPropertyChangedFor( nameof( Caption ) )]标识:在LastName改变后,去通知Caption

public string Caption
{
    get
    {
        return string.Format( "Title:{0}-{1}" , Title , LastName );
    }
}


[ObservableProperty]
[NotifyPropertyChangedFor( nameof( Caption ) )]
private string lastName = "abc";

 

NotifyCanExecuteChangedFor通知依赖命令

在属性IsEnabled改变后,通知命令:ButtonClickCommand

/*
        [NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]
NotifyCanExecuteChangedFor是通知依赖命令(触发命令),相当于set中ButtonClickCommand.NotifyCanExecuteChanged();
*/

[ObservableProperty]
[NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]
private bool isEnabled = false;

//public bool IsEnabled
//{
//    get => isEnabled;
//    set
//    {
//        SetProperty( ref isEnabled , value );

//        //通知命令 已经改变
//        ButtonClickCommand.NotifyCanExecuteChanged();
//    }
//}

//partial void OnIsEnabledChanged ( bool value )
//{
//     //如果上面的[NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]不写,可以这里手动通知更新 
//    //ButtonClickCommand.NotifyCanExecuteChanged();
//}

 

 

命令

RelayCommand标识定义一个命令,如此简单

/*
RelayCommand是定义命令,自动生成的命令名是方法名+Command,并且初始化
例如:下面的会自动生成ButtonClickCommand

CanExecute是指定一个判断方法,判断是否可用
*/

[RelayCommand( CanExecute = nameof( CanButton ) )]
void ButtonClick ()
{
    //点击按钮,修改标题
    Title = "hello(改)";
}

bool CanButton ()
{
    return IsEnabled;
}

//public RelayCommand ButtonClickCommand
//{
//    get;
//}



[RelayCommand]
void ButtonClickPar ( double val )
{
    Title = $"hello(改):{val}";
}

//public RelayCommand<double> ButtonClickParCommand
//{
//    get;
//}

 

 

异步命令

把方法标识为async,即可定义为异步命令,它带有一个IsRunning属性,可以在view中做进度条判断

[RelayCommand]
async Task AsyncButtonClick ()
{
    await Task.Delay( 4800 );
    Title = "hello(Task改)";
}



[RelayCommand]
async Task AsyncButtonParClick ( double val )
{
    await Task.Delay( 4800 );
    Title = $"hello(Task改):{val}";
}
<!--   
特别说明:异步命令会自动控制控件的可见性,并且提供一个IsRunning属性可以判断异步是否完成   
-->
<Button Width="100"
        Height="30"
        Command="{Binding AsyncButtonClickCommand}"
        Content="异步" />
<TextBlock HorizontalAlignment="Center"
           FontSize="20"
           FontStyle="Italic"
           FontWeight="Bold"
           Foreground="Green"
           Text="loading......"
           Visibility="{Binding AsyncButtonClickCommand.IsRunning, Converter={StaticResource myboolconvert}}" />

 

某个属性改变

On+属性Changing  On+属性Changed,可以记录某个属性值变化事件

/*
还可以实现2个方法:OnLastNameChanging OnLastNameChanged (注意2个方法只可以实现其中一个,或者都不实现(不能同时2个))
*/

//partial void OnLastNameChanging ( string value )
//{
//    Debug.WriteLine( value );
//}

partial void OnLastNameChanged ( string value )
{
    // 可以做一些其它事情 例如:属性改变后,消息通知某某某
    Debug.WriteLine( value );



    //说明:如果上面[NotifyPropertyChangedFor( nameof( Caption ) )]不写,可以这里手动通知属性更新
    //OnPropertyChanged( nameof( Caption ) );
}

 

所有属性改变

所有属性改变后都会调用这个事件,参数PropertyName可以区分具体哪个属性

/// <summary>
/// 所有属性改变
/// </summary>
/// <param name="e"></param>
protected override void OnPropertyChanged ( PropertyChangedEventArgs e )
{

    base.OnPropertyChanged( e );

    // 可以获取到是哪个属性改变了
    var _proname = e.PropertyName;
}

 

完整代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

/*
这里演示自动生成属性和命令

1.继承ObservableObject 并且类标记是分部类partial
2.私有变量标记属性 [ObservableProperty]
3.NotifyCanExecuteChangedFor  通知依赖命令
  NotifyPropertyChangedFor    通知依赖属性
4.RelayCommand  定义命令
5.OnPropertyChanged 手动通知属性更新
6.ButtonClickCommand.NotifyCanExecuteChanged() 手动通知命令更新
7.OnLastNameChanging OnLastNameChanged  某个属性改变
8.OnPropertyChanged  所有属性改变
*/

namespace WpfDemoNet6.Demo
{
    public partial class DataViewModel2 : ObservableObject
    {
        /*
        [ObservableProperty]标记后,会自动生成属性(大写命名),例如:下面会自动生成Title

        注意:这个私有变量命名:必须是小写开头,或者下划线,或者m_
        */

        /*
        NotifyPropertyChangedFor 通知依赖属性Caption
        */

        [ObservableProperty]
        [NotifyPropertyChangedFor( nameof( Caption ) )]
        private string title = "hello";

        //public string Title
        //{
        //    get
        //    {
        //        return title;
        //    }
        //    set
        //    {
        //        //title = value;
        //        //PropertyChanged?.Invoke( this , new PropertyChangedEventArgs( "Name" ) );

        //        //SetProperty 相当与设置值,并且PropertyChanged通知调用
        //        SetProperty( ref title , value );
        //    }
        //}


        /*
                [NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]
        NotifyCanExecuteChangedFor是通知依赖命令(触发命令),相当于set中ButtonClickCommand.NotifyCanExecuteChanged();
        */

        [ObservableProperty]
        [NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]
        private bool isEnabled = false;

        //public bool IsEnabled
        //{
        //    get => isEnabled;
        //    set
        //    {
        //        SetProperty( ref isEnabled , value );

        //        //通知命令 已经改变
        //        ButtonClickCommand.NotifyCanExecuteChanged();
        //    }
        //}

        //partial void OnIsEnabledChanged ( bool value )
        //{
        //     //如果上面的[NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]不写,可以这里手动通知更新 
        //    //ButtonClickCommand.NotifyCanExecuteChanged();
        //}




        /*
        RelayCommand是定义命令,自动生成的命令名是方法名+Command,并且初始化
        例如:下面的会自动生成ButtonClickCommand

        CanExecute是指定一个判断方法,判断是否可用
        */

        [RelayCommand( CanExecute = nameof( CanButton ) )]
        void ButtonClick ()
        {
            //点击按钮,修改标题
            Title = "hello(改)";
        }

        bool CanButton ()
        {
            return IsEnabled;
        }

        //public RelayCommand ButtonClickCommand
        //{
        //    get;
        //}



        public DataViewModel2 ()
        {
            //RelayCommand的第一个参数是命令调用语句
            //              第2个参数(可选)是否允许使用
            //ButtonClickCommand = new RelayCommand( () =>
            //{
            //    //点击按钮,修改标题
            //    Title = "hello(改)";
            //} , () =>
            //{
            //    return IsEnabled;
            //} );

            //ButtonClickParCommand = new RelayCommand<double>( ( double val ) =>
            //{
            //    Title = $"hello(改):{val}";
            //} );
        }



        [RelayCommand]
        void ButtonClickPar ( double val )
        {
            Title = $"hello(改):{val}";
        }

        //public RelayCommand<double> ButtonClickParCommand
        //{
        //    get;
        //}



        public string Caption
        {
            get
            {
                return string.Format( "Title:{0}-{1}" , Title , LastName );
            }
        }


        [ObservableProperty]
        [NotifyPropertyChangedFor( nameof( Caption ) )]
        private string lastName = "abc";

        /*
        还可以实现2个方法:OnLastNameChanging OnLastNameChanged (注意2个方法只可以实现其中一个,或者都不实现(不能同时2个))
        */

        //partial void OnLastNameChanging ( string value )
        //{
        //    Debug.WriteLine( value );
        //}

        partial void OnLastNameChanged ( string value )
        {
            // 可以做一些其它事情 例如:属性改变后,消息通知某某某
            Debug.WriteLine( value );



            //说明:如果上面[NotifyPropertyChangedFor( nameof( Caption ) )]不写,可以这里手动通知属性更新
            //OnPropertyChanged( nameof( Caption ) );
        }



        /// <summary>
        /// 所有属性改变
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPropertyChanged ( PropertyChangedEventArgs e )
        {

            base.OnPropertyChanged( e );

            // 可以获取到是哪个属性改变了
            var _proname = e.PropertyName;
        }

    }
}

 

导航

https://github.com/aierong/WpfDemo/tree/main/WpfDemoNet6 (项目地址)

https://github.com/aierong/WpfDemo/blob/main/WpfDemoNet6/Demo/DataViewModel2.cs (代码地址)

 

原文链接:https://www.cnblogs.com/aierong/archive/2023/04/11/17305990.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:CommunityToolkit.Mvvm8.1 viewmodel源生成器写法(3) - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • C#找出字符串中第一个字母并大写的方法

    要找出字符串中第一个字母并大写,可以使用C#中的字符串处理函数和char类型的特性。下面是具体的方法: 1.使用SubString和ToUpper函数找到第一个字符并大写 可以使用SubString函数来截取第一个字符,再使用ToUpper函数将该字符大写。示例代码如下: string str = "apple"; char firstC…

    C# 2023年6月8日
    00
  • 在.NetCore中 DDD中基于mediatr实现领域事件并结合EFCore进行二次封装

    [源代码地址https://github.com/junkai-li/NetCoreKevin]基于NET6搭建跨平台WebApi架构支持单点登录、多缓存、自动任务、分布式、多租户、日志、授权和鉴权 、网关 注册与发现、CAP集成事件、领域事件、 docker部署 **首要要理解什么是领域事件?**领域事件是指发生在特定领域中的事件,是你希望在同一个领域中其…

    C# 2023年5月9日
    00
  • WCF的异常处理

    关于WCF的异常处理,以下是一些基本的知识点和攻略: WCF异常处理基本知识 在WCF中,所有异常都由服务契约(contract)抛出,客户端都可以通过异常处理程序处理这些异常。 WCF中异常处理程序可以在服务端和客户端都实现。 服务端和客户端都可以捕获异常并作出相应的响应,比如返回错误信息给客户端或写入设备日志。 WCF中有一些异常是常见的,比如Timeo…

    C# 2023年5月14日
    00
  • C# Path.Combine(params string[] paths):将多个路径组合成一个完整的路径

    C#的Path.Combine(params string[] paths)方法的作用是将多个字符串路径组合为一个路径,并返回组合后的路径字符串。 使用方法: 传递多个字符串路径作为参数,方法会将路径连接成一个路径,最终返回一个字符串路径。 string path1 = @"\usr\home"; string path2 = &quot…

    C# 2023年4月19日
    00
  • C# winform打印excel的方法

    下面是关于如何使用C# WinForm打印Excel的完整攻略,包含以下几个步骤: 1. 引用Excel Interop 要打印Excel,需要使用Microsoft Excel Interop库。这个库需要先引用才能在程序中使用。下面是引用Excel Interop的具体步骤: 在Visual Studio的工具栏中选择“项目”。 在项目中选择“添加引用”…

    C# 2023年6月7日
    00
  • 基于SqlSugar的开发框架循序渐进介绍(27)– 基于MongoDB的数据库操作整合

    SqlSugar的开发框架本身主要是基于常规关系型数据库设计的框架,支持多种数据库类型的接入,如SqlServer、MySQL、Oracle、PostgreSQL、SQLite等数据库,非关系型数据库的MongoDB数据库也可以作为扩展整合到开发框架里面,通过基类的继承关系很好的封装了相关的基础操作功能,极大的减少相关处理MongoDB的代码,并提供很好的开…

    C# 2023年4月19日
    00
  • Asp Split函数之使用多个分割符的方法

    接下来我会详细讲解 “Asp Split函数之使用多个分割符的方法” 的完整攻略。 什么是Split函数? Split函数是VBScript的内置函数,用于将一个字符串按照指定的分隔符分割成一个数组。在ASP中使用时,可以用来处理表单数据、URL参数等字符串。 Split函数的语法 Split(Expression, [Delimiter, [Limit, …

    C# 2023年6月7日
    00
  • C#中使用Socket获取网页源代码的代码

    使用Socket获取网页源代码的代码,一般需要以下几个步骤: 解析主机名和IP地址: 使用Dns类解析主机名(如www.baidu.com)对应的IP地址。代码如下: IPHostEntry hostEntry = Dns.GetHostEntry("www.baidu.com"); IPAddress ipAddress = hostE…

    C# 2023年6月7日
    00
合作推广
合作推广
分享本页
返回顶部