zoukankan      html  css  js  c++  java
  • MVVM框架搭建

    以下是概要的目录结构,其中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, 2);
                }
                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, 2);
                }
                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 = 0;
                    for (int i = handlers.Count - 1; i >= 0; 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 = 0; 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, -1);
            }
            internal static void AddWeakReferenceHandler(ref List<WeakReference> handlers, EventHandler handler, int defaultListSize)
            {
                if (handlers == null)
                {
                    handlers = (defaultListSize > 0 ? 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 - 1; i >= 0; 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等功能了。

  • 相关阅读:
    github国内加速
    js 关闭MediaDevices.getUserMedia()
    windows server 安装 mysql + nondejs连接mysql
    sql常用语法大全
    当小程序的flex布局遇到button时,justify-content不起作用的原因及解决方案
    c# 使用Sharp7对PLC读写操作
    c#中引用c++动态库
    Python+Django
    python+pycharm+Django报错
    Dapper支持各类数据库(mysql,mssql,FireBird,Oracle)
  • 原文地址:https://www.cnblogs.com/amwuau/p/7513940.html
Copyright © 2011-2022 走看看