微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言

如果对您有所帮助:欢迎赞赏

简化MVVM属性设置和修改 - .NET CORE(C#) WPF开发

阅读导航

  1. 常用类属性设置、获取方式
  2. 二次封装 INotifyPropertyChanged
  3. Demo 展示、源码下载

1. 常用类属性设置、获取方式

public class Student : INotifyPropertyChanged
{
private string name;
public string Name
{
get { return name; }
set
{
if(name != value)
{
name = value;
OnPropertyChanged("Name")
}
}
} #region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}

这种方式总感觉有点啰嗦,如果 Name 属性名修改,字符串 "Name" 还要手动修改,就算 Ctrl+H 替换也容易出错,如果使用下面这种方式,是不是感觉更清爽一点?

public class Student : PropertyNotifyObject
{
public string Name
{
get { return this.GetValue(cu => cu.Name); }
set { this.SetValue(cu => cu.Name, value); }
}
}

2. 二次封装INotifyPropertyChanged

封装的基类PropertyNotifyObject出处我忘了,15年网上找的,源码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Windows;
using System.Windows.Threading; namespace MVVMTest
{ #region 封装WPF属性 public class MyCommMetoh
{
//得到属性的名称
public static string GetPropertyName<T, U>(Expression<Func<T, U>> exp)
{
string _pName = "";
if (exp.Body is MemberExpression)
{
_pName = (exp.Body as MemberExpression).Member.Name;
}
else if (exp.Body is UnaryExpression)
{
_pName = ((exp.Body as UnaryExpression).Operand as MemberExpression).Member.Name;
}
return _pName;
}
} public class NotifyPropertyBase : INotifyPropertyChanged
{
/// <summary>
/// Returns a dispatcher for multi-threaded scenarios
/// </summary>
/// <returns></returns>
public static Dispatcher GetDispatcher(DispatcherObject source = null)
{
//use the application's dispatcher by default
if (Application.Current != null) return Application.Current.Dispatcher; //fallback for WinForms environments
if (source != null && source.Dispatcher != null) return source.Dispatcher; //ultimatively use the thread's dispatcher
return Dispatcher.CurrentDispatcher;
} #region INotifyPropertyChanged
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
GetDispatcher().BeginInvoke((Action)delegate
{
try
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
catch (Exception ex)
{
var msg = string.Format("发送UI属性变化事件异常,属性名称: {0}, 异常详细信息: {1}", propertyName, ex.ToString());
}
}
); }
}
public void OnPropertyChanged<T>(Expression<Func<T>> expression)
{
if (PropertyChanged != null)
{
var propertyName = ((MemberExpression)expression.Body).Member.Name;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
public static class NotifyPropertyBaseEx
{
public static void OnPropertyChanged<T, U>(this T npb, Expression<Func<T, U>> exp) where T : NotifyPropertyBase, new()
{
string _PropertyName = MyCommMetoh.GetPropertyName(exp);
npb.OnPropertyChanged(_PropertyName);
}
} public class PropertyNotifyObject : NotifyPropertyBase, IDisposable
{
public PropertyNotifyObject()
{
} Dictionary<object, object> _ValueDictionary = new Dictionary<object, object>(); #region 根据属性名得到属性值
public T GetPropertyValue<T>(string propertyName)
{
if (string.IsNullOrEmpty(propertyName)) throw new ArgumentException("invalid " + propertyName);
object _propertyValue;
if (!_ValueDictionary.TryGetValue(propertyName, out _propertyValue))
{
_propertyValue = default(T);
_ValueDictionary.Add(propertyName, _propertyValue);
}
return (T)_propertyValue;
}
#endregion public void SetPropertyValue<T>(string propertyName, T value)
{
if (!_ValueDictionary.ContainsKey(propertyName) || _ValueDictionary[propertyName] != (object)value)
{
_ValueDictionary[propertyName] = value;
OnPropertyChanged(propertyName);
}
} #region Dispose
public void Dispose()
{
DoDispose();
}
~PropertyNotifyObject()
{
DoDispose();
}
void DoDispose()
{
if (_ValueDictionary != null)
_ValueDictionary.Clear();
}
#endregion
}
public static class PropertyNotifyObjectEx
{
public static U GetValue<T, U>(this T t, Expression<Func<T, U>> exp) where T : PropertyNotifyObject
{
string _pN = MyCommMetoh.GetPropertyName(exp);
return t.GetPropertyValue<U>(_pN);
} public static void SetValue<T, U>(this T t, Expression<Func<T, U>> exp, U value) where T : PropertyNotifyObject
{
string _pN = MyCommMetoh.GetPropertyName(exp);
t.SetPropertyValue<U>(_pN, value);
}
} #endregion
}

3. Demo展示、源码下载

源码下载:MVVMTest

展示效果:

除非注明,文章均由 Dotnet9 整理发布,欢迎转载。


转载请注明本文地址:https://dotnet9.com/8572.html


欢迎扫描下方二维码关注 Dotnet9 的微信公众号,本站会及时推送最新技术文章



时间如流水,只能流去不流回!

这段时间在家,除了睡觉,也不要忘了学习。

简化MVVM属性设置和修改 - .NET CORE(C#) WPF开发的更多相关文章

  1. Prism+MaterialDesign+EntityFramework Core+Postgresql WPF开发总结 之 基础篇

    本着每天记录一点成长一点的原则,打算将目前完成的一个WPF项目相关的技术分享出来,供团队学习与总结. 总共分三个部分: 基础篇主要争对C#初学者,巩固C#常用知识点: 中级篇主要争对WPF布局与美化, ...

  2. 简易音乐播放器主界面设计 - .NET CORE(C#) WPF开发

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. 简易音乐播放器主界面设计 - .NET CORE(C#) WPF开发 阅读导航 本文背景 代码 ...

  3. Prism+MaterialDesign+EntityFramework Core+Postgresql WPF开发总结 之 中级篇

    本着每天记录一点成长一点的原则,打算将目前完成的一个WPF项目相关的技术分享出来,供团队学习与总结. 总共分三个部分: 基础篇主要争对C#初学者,巩固C#常用知识点: 中级篇主要争对WPF布局与Mat ...

  4. 少量代码设计一个登录界面 - .NET CORE(C#) WPF开发

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. 少量代码设计一个登录界面 - .NET CORE(C#) WPF开发 阅读导航 本文背景 代码 ...

  5. .net core 和 WPF 开发升讯威在线客服与营销系统:背景和产品介绍

    本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程.本产品已经成熟稳定并投入商用. 在线演示环境:https://kf-m.shengxunwei.com ...

  6. .net core 和 WPF 开发升讯威在线客服与营销系统:使用 WebSocket 实现访客端通信

    本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程.本产品已经成熟稳定并投入商用. 在线演示环境:https://kf.shengxunwei.com 注意 ...

  7. .net core 和 WPF 开发升讯威在线客服与营销系统:使用 TCP协议 实现稳定的客服端

    本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程.本产品已经成熟稳定并投入商用. 在线演示环境:https://kf.shengxunwei.com 注意 ...

  8. .net core 和 WPF 开发升讯威在线客服系统:怎样实现拔网线也不丢消息的高可靠通信(附视频)

    本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程.本产品已经成熟稳定并投入商用. 在线演示环境:https://kf.shengxunwei.com 注意 ...

  9. .net core 和 WPF 开发升讯威在线客服与营销系统:系统总体架构

    本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程.本产品已经成熟稳定并投入商用. 在线演示环境:https://kf.shengxunwei.com 注意 ...

随机推荐

  1. 2020寒假学习01 Scala 编程初级实践

    1. 计算级数请用脚本的方式编程计算并输出下列级数的前 n 项之和 Sn,直到 Sn 刚好大于或等于 q为止,其中 q 为大于 0 的整数,其值通过键盘输入. Sn = 2/1+3/2+4/3+... ...

  2. Catch That Cow (简单BFS+剪枝)

    Problem Description Farmer John has been informed of the location of a fugitive cow and wants to cat ...

  3. Python3中的super()函数详解

    关于Python3中的super()函数 我们都知道,在Python3中子类在继承父类的时候,当子类中的方法与父类中的方法重名时,子类中的方法会覆盖父类中的方法, 那么,如果我们想实现同时调用父类和子 ...

  4. 异想家Eclipse的偏好配置

    1.汉化 http://www.eclipse.org/babel/downloads.php 找到Babel Language Pack Zips,下面选自己版本点进去,找到如下类似的中文包: Ba ...

  5. airtest通过包名直接打开app的方法

    工具提供直接打开APP的函数 #输入微信包名,打开微信 start_app("com.tencent.mm")

  6. excle 写入数据库

    龙龙博客:https://www.cnblogs.com/meilong/p/cao-zuoexcel-mo-kuaiopenpyxl.html 1 安装 pip install openpyxl 如 ...

  7. STM8 关闭PWM输出后的电平输出问题解决

    STM系列的单片机PWM输出如果被关断比如用TIM1_CtrlPWMOutputs进行停止输出后,电平的高低处于不确定的状态. 他取决于: 1.GPIO初始化的特性 2.关断那一刻时的电平 3.CCM ...

  8. flask插件全家桶集成学习---持续更新ing

    不得不说flask的设计要比django要小巧精妙的多了,没有那么臃肿,只保留核心功能,其他的都需要自己引入,即各种各样的插件来满足我们的需求,我这里记录一下自己学习项目中用的插件使用方法和一些技巧总 ...

  9. 3万字总结,Mysql优化之精髓

    本文知识点较多,篇幅较长,请耐心学习 MySQL已经成为时下关系型数据库产品的中坚力量,备受互联网大厂的青睐,出门面试想进BAT,想拿高工资,不会点MySQL优化知识,拿offer的成功率会大大下降. ...

  10. C#系列之占位符的使用方法(二)

    今天,我将简单记录下占位符的使用方法 首先,我们来看不使用占位符的方法来代码输出 int number = 10; int number_1 = 20; int number_2 = 30; Cons ...