MVVM框架搭建
2024-09-06 14:30:41
以下是概要的目录结构,其中View,ViewModel,Model正代表的是MVVM的标识。
View:页面window或者UserControl
Model:数据模型对象
ViewModel:与View交互binding,逻辑业务处理。
当然可以根据自己项目的具体情况,再进行拆分,包括业务逻辑,
服务数据分离,日志分离等。
其中主要的两个文件:
ViewModelBase.cs
ViewModel的绑定
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading; namespace Common
{
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
} public static class ViewModelBaseEx
{
public static void OnPropertyChanged<T, TProperty>(this T PropetyChangedBase, Expression<Func<T, TProperty>> propertyName)
where T : ViewModelBase
{
var propertyNameExpression = propertyName.Body as MemberExpression;
if (propertyNameExpression != null)
{
if (Dispatcher.CurrentDispatcher.Thread == Thread.CurrentThread)
{
PropetyChangedBase.OnPropertyChanged(propertyNameExpression.Member.Name);
}
else
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
PropetyChangedBase.OnPropertyChanged(propertyNameExpression.Member.Name);
}));
}
}
}
}
}
事件binding
DeletgateCommand.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input; namespace Common
{
public class DelegateCommand : System.Windows.Input.ICommand
{
public DelegateCommand(Action executeMethod)
: this(executeMethod, null, false)
{
}
public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod)
: this(executeMethod, canExecuteMethod, false)
{
}
public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod, bool isAutomaticRequeryDisabled)
{
if (executeMethod == null)
{
throw new ArgumentNullException("executeMethod");
}
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
_isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
}
public bool CanExecute()
{
if (_canExecuteMethod != null)
{
return _canExecuteMethod();
}
return true;
}
public void Execute()
{
if (_executeMethod != null)
{
_executeMethod();
}
}
public bool IsAutomaticRequeryDisabled
{
get
{
return _isAutomaticRequeryDisabled;
}
set
{
if (_isAutomaticRequeryDisabled != value)
{
if (value)
{
CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
}
else
{
CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
}
_isAutomaticRequeryDisabled = value;
}
}
}
public void RaiseCanExecuteChanged()
{
OnCanExecuteChanged();
}
protected virtual void OnCanExecuteChanged()
{
CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
}
public event EventHandler CanExecuteChanged
{
add
{
if (!_isAutomaticRequeryDisabled)
{
CommandManager.RequerySuggested += value;
}
CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, );
}
remove
{
if (!_isAutomaticRequeryDisabled)
{
CommandManager.RequerySuggested -= value;
}
CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
}
}
bool System.Windows.Input.ICommand.CanExecute(object parameter)
{
return CanExecute();
}
void System.Windows.Input.ICommand.Execute(object parameter)
{
Execute();
}
private readonly Action _executeMethod = null;
private readonly Func<bool> _canExecuteMethod = null;
private bool _isAutomaticRequeryDisabled = false;
private List<WeakReference> _canExecuteChangedHandlers;
}
public class DelegateCommand<T> : System.Windows.Input.ICommand
{
public DelegateCommand(Action<T> executeMethod)
: this(executeMethod, null, false)
{
}
public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
: this(executeMethod, canExecuteMethod, false)
{
}
public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod, bool isAutomaticRequeryDisabled)
{
if (executeMethod == null)
{
throw new ArgumentNullException("executeMethod");
}
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
_isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
}
public bool CanExecute(T obj)
{
if (_canExecuteMethod != null)
{
return _canExecuteMethod(obj);
}
return true;
}
public void Execute(T obj)
{
if (_executeMethod != null)
{
_executeMethod(obj);
}
}
public bool IsAutomaticRequeryDisabled
{
get
{
return _isAutomaticRequeryDisabled;
}
set
{
if (_isAutomaticRequeryDisabled != value)
{
if (value)
{
CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
}
else
{
CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
}
_isAutomaticRequeryDisabled = value;
}
}
}
public void RaiseCanExecuteChanged()
{
OnCanExecuteChanged();
}
protected virtual void OnCanExecuteChanged()
{
CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
}
public event EventHandler CanExecuteChanged
{
add
{
if (!_isAutomaticRequeryDisabled)
{
CommandManager.RequerySuggested += value;
}
CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, );
}
remove
{
if (!_isAutomaticRequeryDisabled)
{
CommandManager.RequerySuggested -= value;
}
CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
}
}
bool System.Windows.Input.ICommand.CanExecute(object parameter)
{
return CanExecute((T)parameter);
}
void System.Windows.Input.ICommand.Execute(object parameter)
{
Execute((T)parameter);
}
private readonly Action<T> _executeMethod = null;
private readonly Func<T, bool> _canExecuteMethod = null;
private bool _isAutomaticRequeryDisabled = false;
private List<WeakReference> _canExecuteChangedHandlers;
}
//采用弱引用,避免内存泄漏
internal class CommandManagerHelper
{
internal static void CallWeakReferenceHandlers(List<WeakReference> handlers)
{
if (handlers != null)
{
// Take a snapshot of the handlers before we call out to them since the handlers
// could cause the array to me modified while we are reading it.
EventHandler[] callees = new EventHandler[handlers.Count];
int count = ;
for (int i = handlers.Count - ; i >= ; i--)
{
WeakReference reference = handlers[i];
EventHandler handler = reference.Target as EventHandler;
if (handler == null)
{
// Clean up old handlers that have been collected
handlers.RemoveAt(i);
}
else
{
callees[count] = handler;
count++;
}
}
// Call the handlers that we snapshotted
for (int i = ; i < count; i++)
{
EventHandler handler = callees[i];
handler(null, EventArgs.Empty);
}
}
}
internal static void AddHandlersToRequerySuggested(List<WeakReference> handlers)
{
if (handlers != null)
{
foreach (WeakReference handlerRef in handlers)
{
EventHandler handler = handlerRef.Target as EventHandler;
if (handler != null)
{
CommandManager.RequerySuggested += handler;
}
}
}
}
internal static void RemoveHandlersFromRequerySuggested(List<WeakReference> handlers)
{
if (handlers != null)
{
foreach (WeakReference handlerRef in handlers)
{
EventHandler handler = handlerRef.Target as EventHandler;
if (handler != null)
{
CommandManager.RequerySuggested -= handler;
}
}
}
}
internal static void AddWeakReferenceHandler(ref List<WeakReference> handlers, EventHandler handler)
{
AddWeakReferenceHandler(ref handlers, handler, -);
}
internal static void AddWeakReferenceHandler(ref List<WeakReference> handlers, EventHandler handler, int defaultListSize)
{
if (handlers == null)
{
handlers = (defaultListSize > ? new List<WeakReference>(defaultListSize) : new List<WeakReference>());
}
handlers.Add(new WeakReference(handler));
}
internal static void RemoveWeakReferenceHandler(List<WeakReference> handlers, EventHandler handler)
{
if (handlers != null)
{
for (int i = handlers.Count - ; i >= ; i--)
{
WeakReference reference = handlers[i];
EventHandler existingHandler = reference.Target as EventHandler;
if ((existingHandler == null) || (existingHandler == handler))
{
// Clean up old handlers that have been collected
// in addition to the handler that is to be removed.
handlers.RemoveAt(i);
}
}
}
}
}
}
这样基本的内容就齐了,简单的MVVM可以实现binding等功能了。
最新文章
- socket通信之eofexception
- amCharts图表组件
- NPM使用详解(下)
- DOS下快速删除文件
- android 完全退出应用程序(重要)
- vim插件开发初步
- hdu1430魔板(BFS+康托展开)
- MySQL分库分表备份脚本
- spring使用ehcache
- CN消息的来源——父窗口不知道怎么处理,于是把这个消息加上CN_BASE在分发到实际的子窗体
- [C#]asp.net开发微信公众平台----目录汇总-持续更新
- 【ODPS】TableTunnel单线程简单下载事例
- C#枚举的简单使用
- .net WebApi中使用swagger生成WepApi集成测试工具
- 定位linux jdk安装路径
- Confluence 6 修改 Home 目录的位置
- [转]Anatomy of a Program in Memory
- Jenkins触发远程Job的几种方式
- 【JSP】JSP指令
- Bing词典vs有道词典比对测试报告——功能篇之辅助功能,差异化功能及软件的效能