2016年2月29日月曜日

ViewModelBaseの代替?

【参考】http://zecl.hatenablog.com/entry/20091211/p1


 【IImpleNotifyPropertyChanged.cs】
using System;
using System.Linq;
using System.Linq.Expressions;
using System.ComponentModel;

namespace ClassLibrary1
{
    /// <summary>
    /// IImpleNotifyPropertyChangedインターフェイス
    /// 
    /// INotifyPropertyChangedの実装をある程度抽象化し、簡易な実装を提供します。
    /// </summary>
    public interface IImpleNotifyPropertyChanged : INotifyPropertyChanged
    {
        /// <summary>
        /// PropertyChangedの再定義
        /// (INotifyPropertyChangedのPropertyChangedを隠蔽する)
        /// </summary>
        new event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// PropertyChangedEventHandlerを取得します。
        /// </summary>
        PropertyChangedEventHandler PropertyChangedHandler { get; }
    }

    /// <summary>
    /// IImpleNotifyPropertyChangedインターフェイスについて拡張メソッド提供
    /// </summary>
    public static class IImpleNotifyPropertyChangedExtentions
    {
        /// <summary>
        /// プロパティの変更を通知します。
        /// </summary>
        /// <param name="self">対象</param>
        /// <param name="targets">プロパティ変更通知対象の名称群</param>
        private static void OnPropertyChanged<TObject>(this TObject self, params string[] propertyNames)
            where TObject : IImpleNotifyPropertyChanged
        {
            if (self == null) return;
            if (self.PropertyChangedHandler == null) return;

            foreach (var propertyName in propertyNames)
                self.PropertyChangedHandler(self, new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// プロパティの変更を通知します。
        /// </summary>
        /// <typeparam name="TObject"></typeparam>
        /// <typeparam name="TExpression"></typeparam>
        /// <param name="self">対象</param>
        /// <param name="expressions">プロパティ変更通知対象の名称を取得するExpression群</param>
        public static void OnPropertyChanged<TObject, TExpression>(this TObject self, params Expression<Func<TObject, TExpression>>[] expressions)
            where TObject : IImpleNotifyPropertyChanged
        {
            var propertyNames = from e in expressions
                                select ((MemberExpression)e.Body).Member.Name;
            self.OnPropertyChanged(propertyNames.ToArray());
        }
    }

    /// <summary>
    /// INotifyPropertyChangedインターフェイスについて拡張メソッドを提供
    /// </summary>
    public static class INotifyPropertyChangedExtentions
    {
        /// <summary>
        /// プロパティ変更イベントの関連付け補助
        /// </summary>
        /// <typeparam name="TObject"></typeparam>
        /// <typeparam name="TExpression"></typeparam>
        /// <param name="self"></param>
        /// <param name="expressions"></param>
        /// <param name="handler"></param>
        public static void AddPropertyChanged<TObject, TExpression>(this TObject self, Expression<Func<TObject, TExpression>> expressions, Action<TObject> handler)
            where TObject : INotifyPropertyChanged
        {
            if (self == null) return;
            var propName = ((MemberExpression)expressions.Body).Member.Name;
            self.PropertyChanged += (sender, e) =>
            {
                if (e.PropertyName == propName)
                    handler(self);
            };
        }
    }
}

0 件のコメント:

コメントを投稿