私は次のクラスを持っています...
class ExpressionBinder<T>
{
public Func<T> Getter;
public Action<T> Setter;
public T Value
{
get { return Getter.Invoke(); }
set { Setter.Invoke(value); }
}
public ExpressionBinder(Func<T> getter, Action<T> setter)
{
Getter = getter;
Setter = setter;
}
}
class ComparisonBinder<TSource, TValue> : ExpressionBinder<bool>, INotifyPropertyChanged
{
private TSource instance;
private TValue comparisonValue;
private PropertyInfo pInfo;
public event PropertyChangedEventHandler PropertyChanged;
public ComparisonBinder(TSource instance, Expression<Func<TSource, TValue>> property, TValue comparisonValue) : base(null,null)
{
pInfo = GetPropertyInfo(property);
this.instance = instance;
this.comparisonValue = comparisonValue;
Getter = GetValue;
Setter = SetValue;
}
private bool GetValue()
{
return comparisonValue.Equals(pInfo.GetValue(instance, null));
}
private void SetValue(bool value)
{
if (value)
{
pInfo.SetValue(instance, comparisonValue,null);
NotifyPropertyChanged("CustomerName");
}
}
private void NotifyPropertyChanged(string pName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(pName));
}
}
/// <summary>
/// Adapted from surfen's answer (https://stackoverflow.com/a/10003320/219838)
/// </summary>
private PropertyInfo GetPropertyInfo(Expression<Func<TSource, TValue>> propertyLambda)
{
Type type = typeof(TSource);
MemberExpression member = propertyLambda.Body as MemberExpression;
if (member == null)
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a method, not a property.",
propertyLambda));
PropertyInfo propInfo = member.Member as PropertyInfo;
if (propInfo == null)
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a field, not a property.",
propertyLambda));
if (type != propInfo.ReflectedType &&
!type.IsSubclassOf(propInfo.ReflectedType))
throw new ArgumentException(string.Format(
"Expresion '{0}' refers to a property that is not from type {1}.",
propertyLambda,
type));
return propInfo;
}
}
クラスを使用した私のコードComparisonBinder
は次のとおりです。
radioMale.DataBindings.Add(
"Checked",
new ComparisonBinder<DataClass, GenderEnum>(DataObj, (x) => x.Gender, GenderEnum.Male),
"Value",
false,
DataSourceUpdateMode.OnPropertyChanged);
radioFemale.DataBindings.Add(
"Checked",
new ComparisonBinder<DataClass, GenderEnum>(DataObj, (x) => x.Gender, GenderEnum.Male),
"Value",
false,
DataSourceUpdateMode.OnPropertyChanged);
コントロールのバインドされたプロパティの値を生成する式を使用して、多くのコントロールを同じプロパティにバインドできます。コントロールからオブジェクトまで美しく機能します。(このクラスとこの質問の使用について詳しく知りたい場合)
今、私は逆の方向に進む必要があります。オブジェクトを更新すると (get 式の結果が変更されます)、バインドされたコントロールを更新する必要があります。を実装してみましたINotifyPropertyChanged
が、違いはありませんでした。
奇妙なことに、コントロールDataSourceUpdateMode
を に設定するとOnPropertyChanged
、チェックしたラジオを変更できなくなります。