WPF ModeBase
由于个人不喜欢定义那么多变量,而在wpf的vm中需触发更新的变量都要定义一个字段和属性。
例如:
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
RaisePropertyChanged(nameof(Name));
}
}
为了在ViewModel中改变了Name的值,能够改变View中显示的值,需定义_name字段和Name属性两个变量。
现做如下更改,创建ModelBase类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using System.Runtime.Caching;
using System.Windows;
public class ModelBase : INotifyPropertyChanged
{
public static T MemoryGetProperty<T>([CallerMemberName] string propertyName = null)
{
if (MemoryCache.Default.Contains(propertyName))
{
return (T)MemoryCache.Default[propertyName];
}
return default;
}
public static T MemoryGetPropertyOrSetDefault<T>(T tDefault, [CallerMemberName] string propertyName = null)
{
if (MemoryCache.Default.Contains(propertyName))
{
return (T)MemoryCache.Default[propertyName];
}
MemorySetProperty(tDefault, propertyName);
return tDefault;
}
public static void MemorySetProperty<T>(T t, [CallerMemberName] string propertyName = null)
{
if (t == null)
{
MemoryCache.Default.Remove(propertyName);
}
else
{
MemoryCache.Default[propertyName] = t;
}
}
public ModelBase()
{
_cache = new MemoryCache(Guid.NewGuid().ToString());
}
private Dictionary<string, ICommand> _dictCommands = new Dictionary<string, ICommand>();
public ICommand GetCommand(ICommand command, [CallerMemberName] string name = null)
{
if (!_dictCommands.ContainsKey(name))
{
_dictCommands[name] = command;
}
return _dictCommands[name];
}
private MemoryCache _cache;
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public T GetProperty<T>([CallerMemberName] string propertyName = null)
{
if (_cache.Contains(propertyName))
{
return (T)_cache[propertyName];
}
return default;
}
public T GetPropertyOrSetDefault<T>(T tDefault, [CallerMemberName] string propertyName = null)
{
if (_cache.Contains(propertyName))
{
return (T)_cache[propertyName];
}
SetProperty(tDefault, false, propertyName);
return tDefault;
}
public void SetProperty<T>(T t, bool isNotify = true, [CallerMemberName] string propertyName = null)
{
if (t == null)
{
_cache.Remove(propertyName);
}
else
{
_cache[propertyName] = t;
}
if (isNotify)
{
RaisePropertyChanged(propertyName);
}
}
}
- 利用MemoryCache进行缓存变量值(MemoryCache.Default缓存所有VM公共变量,利用GUID创建的MemoryCache缓存对应的VM中的变量);
- 由于MemoryCache中不能缓存null值,所以添加对null值得单独处理;
对VM继承ModeBase后,代码就可以这样修改:
public string Name
{
get
{
return GetProperty<string>();
}
set
{
SetProperty(value);
}
}
若是需要赋初值:
public string Name
{
get
{
return GetPropertyOrSetDefault<string>("NB");
}
set
{
SetProperty(value);
}
}
这样优化后,代码更整洁明了,也不会因变量太多导致逻辑杂乱。