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);
        }
    }
}
  1. 利用MemoryCache进行缓存变量值(MemoryCache.Default缓存所有VM公共变量,利用GUID创建的MemoryCache缓存对应的VM中的变量);
  2. 由于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);
    }
}

 

这样优化后,代码更整洁明了,也不会因变量太多导致逻辑杂乱。

posted @ 2022-09-13 11:38  Bridgebug  阅读(67)  评论(0编辑  收藏  举报