简化MVVM属性设置和修改 - .NET CORE(C#) WPF开发
简化MVVM属性设置和修改 - .NET CORE(C#) WPF开发
阅读导航
- 常用类属性设置、获取方式
- 二次封装 INotifyPropertyChanged
- 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 的微信公众号,本站会及时推送最新技术文章
时间如流水,只能流去不流回!
这段时间在家,除了睡觉,也不要忘了学习。
时间如流水,只能流去不流回。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?