ViewModelBase

以前の記事で DataAnnotations のデータ検証アトリビュートを利用できる ViewModelBase を作りましたが、コード例を書くだけにはちょっと大げさだったり、ModelState クラスが .NET Framework 4 + ASP.NET MVC 4 では System.Web.Mvc 名前空間(アセンブリは System.Web.Mvc)にあったりすることから、ごく単純な ViewModelBase クラスを書いてみます(まぁ、ModelState クラスを自前で実装しちゃえば System.Web.Mvc への依存はなくなるんですけど、さらに大げさになっちゃいますし 😆 )。

(2013/12/29 追記)
ソースコードのダウンロードページを作成しました。

PropertyHelper と RelayCommand に変更はありません。

using System;
using System.Linq.Expressions;

namespace MakCraft.ViewModels
{
    public static class PropertyHelper
    {
        // http://blogs.msdn.com/b/csharpfaq/archive/2010/03/11/how-can-i-get-objects-and-property-values-from-expression-trees.aspx
        /// <summary>
        /// 引数で渡されたプロパティから当該プロパティの名前を返します。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="e"></param>
        /// <returns></returns>
        public static string GetName<T>(Expression<Func<T>> e)
        {
            var member = (MemberExpression)e.Body;
            return member.Member.Name;
        }
    }
}
using System;
using System.Windows.Input;

namespace MakCraft.ViewModels
{
    /// <summary>
    /// デリゲートを呼び出すことによって、コマンドを他のオブジェクトに中継する。CanExecute メソッドの既定値は 'true'。
    /// </summary>
    public class RelayCommand : ICommand
    {
        #region fields

        private readonly Action<object> execute;
        private readonly Predicate<object> canExecute;

        #endregion // Fields

        #region Constructor

        /// <summary>
        /// 実行可否判定のないコマンドを作成
        /// </summary>
        /// <param name="execute"></param>
        public RelayCommand(Action<object> execute)
            : this(execute, null)
        {
        }

        /// <summary>
        /// コマンドを作成
        /// </summary>
        /// <param name="execute"></param>
        /// <param name="canExecute"></param>
        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("param: execute");

            this.execute = execute;
            this.canExecute = canExecute;
        }

        #endregion // Constructor

        #region ICommand Members

        public bool CanExecute(object parameter)
        {
            return canExecute == null ? true : canExecute(parameter);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            execute(parameter);
        }

        #endregion // ICommand Members
    }
}

ViewModelBase クラスです。

引数にプロパティをセットできるように void RaisePropertyChanged<T>(Expression<Func<T>> e) メソッドを追加しました。RaisePropertyChanged(()=> プロパティ) と書くことができます。

using System;
using System.ComponentModel;
using System.Linq.Expressions;

namespace MakCraft.ViewModels
{
    /// <summary>
    /// プロパティ変更通知を実装したビューモデルの基底クラス
    /// </summary>
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public ViewModelBase() { }

        protected void RaisePropertyChanged<T>(Expression<Func<T>> e)
        {
            RaisePropertyChanged(PropertyHelper.GetName(e));
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

 


ViewModelBase」への6件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です