MVVM简单案例(含基类的方法)

基础类库

NotifyPropertyChanged 数据属性

using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace MvvmBase
{
    class NotifyPropertyObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        #region 简单实现
        //对事件进行简单封装
        //public void RaisePropertyChanged(string propertyName)
        //{
        //    if (propertyName != null)
        //    {
        //        //告诉Binding那个属性的值发生了变化
        //        this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        //    }
        //}
        #endregion

        #region 使用 ?. Null条件运算符进行简化
        //简化
        //public void SetProperty(string propertyName)
        //{
        //    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        //}
        #endregion

        #region 配合Prism扩展进行封装
        //配合Prism扩展进行封装  使用Prism扩展 语法糖propp  
        protected bool SetProperty<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
        {
            if (!EqualityComparer<T>.Default.Equals(field, newValue))
            {
                field = newValue;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
                return true;
            }
            return false;
        }
        #endregion
    }
}

MVVM DelegateCommand 命令属性

using System;
using System.Windows.Input;

namespace MvvmBase
{
    class DelegateCommand : ICommand
    {
        #region 简单实现
        //声明一个Action的委托,当Execute执行的时候,做一件事情
        //public Action<object> ExeuteActio { get; set; }
        //public Func<object, bool> CanExecuteFunc { get; set; }

        //public event EventHandler CanExecuteChanged;

        //public bool CanExecute(object parameter)
        //{
        //    if (this.CanExecuteFunc == null)
        //    {
        //        return true;
        //    }
        //    this.CanExecuteFunc(parameter);
        //    return false;
        //}

        //public void Execute(object parameter)
        //{
        //    if (this.ExeuteActio == null)
        //    {
        //        return;
        //    }
        //    this.ExeuteActio(parameter);
        //}
        #endregion
        #region 使用拉姆达表达式 =>   ?. NULL条件运算符   ?? NULL合并运算符 进行简化
        //简化版
        private readonly Action<object> _executeAction;
        private readonly Func<object, bool> _canExecuteAction;

        public event EventHandler CanExecuteChanged;

        public DelegateCommand(Action<object> executeAction, Func<object, bool> canExecuteAction)
        {
            _executeAction = executeAction;
            _canExecuteAction = canExecuteAction;
        }

        public void Execute(object parameter) => _executeAction(parameter);

        public bool CanExecute(object parameter) => _canExecuteAction?.Invoke(parameter) ?? true;

        public void InvokeCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
        #endregion
    }
}

使用PropertyChanged.Fody简化NotifyPropertyChanged

使用方法

  1. 通过Nuget安装PropertyChanged.Fody。
  2. 安装完成后,会在项目中,添加FodyWeavers.xml文件,这是Fody的配置文件。
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
  <PropertyChanged />
</Weavers>

说明

项目中所有标记有[AddINotifyPropertyChangedInterface]特性,或者实现了INotifyPropertyChanged的类,都将自动在其属性中实现通知相关的代码,除非属性被显示标记为不通知。

  • 程序中的代码:
[AddINotifyPropertyChangedInterface]
class VM_MainWindow
{

    public int x { get; set; }
    public int y { get; set; }
    public string btn { get; set; }

    public VM_MainWindow()
    {
        x = 10;
        y = 20;
        btn = "计算";
    }
}
  • 编译后的代码:
using System;
using System.CodeDom.Compiler;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using 测试2;

internal class VM_MainWindow : INotifyPropertyChanged
{
	public int x
	{
		[CompilerGenerated]
		get
		{
			return <x>k__BackingField;
		}
		[CompilerGenerated]
		set
		{
			if (<x>k__BackingField != value)
			{
				<x>k__BackingField = value;
				<>OnPropertyChanged(<>PropertyChangedEventArgs.x);
			}
		}
	}

	public int y
	{
		[CompilerGenerated]
		get
		{
			return <y>k__BackingField;
		}
		[CompilerGenerated]
		set
		{
			if (<y>k__BackingField != value)
			{
				<y>k__BackingField = value;
				<>OnPropertyChanged(<>PropertyChangedEventArgs.y);
			}
		}
	}

	public string btn
	{
		[CompilerGenerated]
		get
		{
			return <btn>k__BackingField;
		}
		[CompilerGenerated]
		set
		{
			if (!string.Equals(<btn>k__BackingField, value, StringComparison.Ordinal))
			{
				<btn>k__BackingField = value;
				<>OnPropertyChanged(<>PropertyChangedEventArgs.btn);
			}
		}
	}

	[field: NonSerialized]
	public event PropertyChangedEventHandler PropertyChanged;

	public VM_MainWindow()
	{
		x = 10;
		y = 20;
		btn = "计算";
	}

	[GeneratedCode("PropertyChanged.Fody", "3.2.9.0")]
	[DebuggerNonUserCode]
	protected void <>OnPropertyChanged(PropertyChangedEventArgs eventArgs)
	{
		this.PropertyChanged?.Invoke(this, eventArgs);
	}
}

代码模板 Code Snippet

工具-》代码片段管理器-》CSharp-》Visual C#-》打开模板文件夹-》复制一个模板-》修改内容-》保存至代码文件夹中

数据属性 快捷方式propn

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>propn</Title>
			<Shortcut>propn</Shortcut>
			<Description>属性和支持字段通知的代码片段</Description>
			<Author>Fish Pond816</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>type</ID>
					<ToolTip>属性类型</ToolTip>
					<Default>int</Default>
				</Literal>
				<Literal>
					<ID>property</ID>
					<ToolTip>属性名</ToolTip>
					<Default>MyProperty</Default>
				</Literal>
				<Literal>
					<ID>field</ID>
					<ToolTip>支持此属性的变量</ToolTip>
					<Default>myVar</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp">
        <![CDATA[private $type$ $field$;

	public $type$ $property$
	{
		get { return $field$;}
		set 
    {
			$field$ = value;
      this.RaisePropertyChanged("$property$");
    }
	}
	$end$]]>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

命令属性 快捷方式pronc

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets
    xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>propc</Title>
      <Shortcut>propc</Shortcut>
      <Author>Fish Pond816</Author>
      <Description>
        使用Execute方法创建DelegateCommand属性
      </Description>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>fieldName</ID>
          <ToolTip>
            包含DelegateCommand的后备字段的名称
          </ToolTip>
          <Default>_fieldName</Default>
        </Literal>
        <Literal>
          <ID>CommandName</ID>
          <ToolTip>
            DelegateCommand的名称
          </ToolTip>
          <Default>CommandName</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[private DelegateCommand $fieldName$;
        public DelegateCommand $CommandName$ => 
            $fieldName$ ?? ($fieldName$ = new DelegateCommand(Execute$CommandName$));
            
        void Execute$CommandName$(object commandParameter)
        {
            $end$
        }]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

示例:

NotifyPropertyChanged类

class NotifyPropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string propertyName) => PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
}

DelegateCommand 类

class DelegateCommand : ICommand
{
    private readonly Func<object, bool> _canExecuteAction;
    private readonly Action<object> _executeAction;
    public DelegateCommand(Action<object> executeAction, Func<object,bool> canExecuteAction = null)
    {
        _executeAction = executeAction;
        _canExecuteAction = canExecuteAction;
    }

    public event EventHandler CanExecuteChanged;
    public bool CanExecute(object parameter)=> _canExecuteAction?.Invoke(parameter) ?? true;
    public void Execute(object parameter) => _executeAction(parameter);
    public void InvokeCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);

}

View.Xaml

<StackPanel>
    <TextBox Text="{Binding X}"/>
    <TextBox Text="{Binding Y}"/>
    <Button Command="{Binding AddCommadn}" Content="{Binding Btn}"/>
</StackPanel>

<!--C#代码-->
public MainWindowView()
{
    InitializeComponent();
    this.DataContext =new MainWindowViewModel();
}

ViewModel.cs:

class MainWindowViewModel:NotifyPropertyChanged
    {
        private int _x;

        public int X
        {
            get { return _x; }
            set {
                _x = value;
                this.RaisePropertyChanged("X");
            }
        }

        private int _y;

        public int Y
        {
            get { return _y; }
            set {
                _y = value;
                this.RaisePropertyChanged("Y");
            }
        }

        private string _btn;

        public string Btn
        {
            get { return _btn; }
            set {
                _btn = value;
                this.RaisePropertyChanged("Btn");
            }
        }

        private DelegateCommand _addCommand;
        public DelegateCommand AddCommadn =>
            _addCommand ?? (_addCommand = new DelegateCommand(ExecuteAddCommadn));
        void ExecuteAddCommadn(object commandParameter)
        {
            int Z = X   + Y;
            MessageBox.Show($"结果是:{Z}");
        }

        public MainWindowViewModel()
        {
            X = 20;
            Y = 40;
            Btn = "点击";
        }
    }
登峰造极的成就源于自律
原文地址:https://www.cnblogs.com/fishpond816/p/13490688.html