謎の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
}
これでデザイナも正しく表示されるようになった。 さて、自動生成機能に戻ろう。