謎のTypeLoadException その2
自身で定義したViewModelにIDataErrorInfoを実装すると発生するTypeLoadExceptionだが、結局原因が分らない。
そもそもSystem.ComponentModel.IDataErrorInfoは参照できるものの、元々WPFで使用してきたインタフェースでありWindows Phone 7のProfileでは使えるものではないのかもしれない。
ということでViewModelでIDataErrorInfoを実装するのは止めることにする。取りあえずはSilverlightで追加されたINotifyDataErrorInfoインタフェースを簡易に実装しておき、いずれは追加する属性ベースのバリデーション(これも恐らくWindows Phoneではサポートされていない)に合わせて汎用的な実装をしていこうと思う。
ViewModel.cs (INotifyDataErrorInfo版)
public class ViewModel : INotifyPropertyChanged, INotifyDataErrorInfo { private readonly IDictionary> _errors = new Dictionary >(); public event PropertyChangedEventHandler PropertyChanged; public event EventHandler ErrorsChanged; public bool IsInDesignMode { get { return DesignerProperties.IsInDesignTool; } } protected void RaisePropertyChanged (Expression > propertyExpresssion) { var propertyName = ViewModel.ExtractPropertyName(propertyExpresssion); this.RaisePropertyChanged(propertyName); } protected virtual void RaisePropertyChanged(string propertyName) { var handler = this.PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } protected void ExecuteOnUIThread(Action action) { var dispatcher = Deployment.Current.Dispatcher; if (dispatcher.CheckAccess()) { action(); } else { dispatcher.BeginInvoke(action); } } public static string ExtractPropertyName (Expression > propertyExpression) { if (propertyExpression == null) { throw new ArgumentNullException("propertyExpression"); } var memberExpression = propertyExpression.Body as MemberExpression; if (memberExpression == null) { throw new ArgumentException("propertyExpression"); } var property = memberExpression.Member as PropertyInfo; if (property == null) { throw new ArgumentException("propertyExpression"); } var getMethod = property.GetGetMethod(true); if (getMethod.IsStatic) { throw new ArgumentException("propertyExpression"); } return memberExpression.Member.Name; } #region INotifyDataErrorInfo メンバ public IEnumerable GetErrors(string propertyName) { List errorList; if ( _errors.TryGetValue(propertyName, out errorList) ) { foreach (var error in errorList) { yield return error; } } } public bool HasErrors { get { return _errors.Count > 0; } } #endregion }
これでデザイナも正しく表示されるようになった。 さて、自動生成機能に戻ろう。