zoukankan      html  css  js  c++  java
  • 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 = "点击";
            }
        }
    
    登峰造极的成就源于自律
  • 相关阅读:
    emqttd的启动脚本
    vue2的全局变量
    windows 上优雅的安装 node 和 npm
    Intent数据清理
    android 滑动刷新的实验总结
    Android 音量键拦截
    多进程通讯笔记 android aidl
    perl-Thread-Queue for openwrt
    openwrt的编译环境
    高德地图白屏的问题
  • 原文地址:https://www.cnblogs.com/fishpond816/p/13490688.html
Copyright © 2011-2022 走看看