Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何动态创建绑定代理?_C#_.net_Winforms_Data Binding - Fatal编程技术网

C# 如何动态创建绑定代理?

C# 如何动态创建绑定代理?,c#,.net,winforms,data-binding,C#,.net,Winforms,Data Binding,我有一个配置对象,它有一个enum,我想把一堆RadioButton绑定到同一个属性。正如我看到自己重复的那样,有时我试图想出一个通用的解决方案,将多个项绑定到同一个属性。我找到的解决方案是创建一个执行表达式的代理。请参阅下面的代码 public enum GenderEnum { Male, Female } public class DataClass { public GenderEnum Gender { get; set; } } class Express

我有一个配置对象,它有一个
enum
,我想把一堆
RadioButton
绑定到同一个属性。正如我看到自己重复的那样,有时我试图想出一个通用的解决方案,将多个项绑定到同一个属性。我找到的解决方案是创建一个执行表达式的代理。请参阅下面的代码

public enum GenderEnum
{
    Male,
    Female
}

public class DataClass
{
    public GenderEnum Gender { get; set; }
}

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;
    }
}
不幸的是,我只能说我想如何使用它

radioMale.DataBindings.Add("Checked", 
    new ComparisonBinder<ConfigClass>((c) c.Gender, GenderEnum.Male), 
    "Value");
radioFemale.DataBindings.Add("Checked", 
    new ComparisonBinder<ConfigClass>((c) c.Gender, GenderEnum.Female),
    "Value");
用法:

radioMale.DataBindings.Add("Checked", 
    new ComparisonBinder<DataClass,GenderEnum>(DataObj, (x) => x.Gender, GenderEnum.Male), "Value");
radioFemale.DataBindings.Add("Checked", 
    new ComparisonBinder<DataClass,GenderEnum>(DataObj, (x) => x.Gender, GenderEnum.Female), "Value");
radioMale.DataBindings.Add(“选中”,
新的比较指标(DataObj,(x)=>x.性别,GenderEnum.男性),“值”);
radioFemale.DataBindings.Add(“选中”,
新的比较指标(DataObj,(x)=>x.性别,GenderEnum.女性),“值”);

我认为这可以通过使用
PropertyInfo
和一些lambda magic来实现:

class ComparisonBinder<TSource,TValue> : ExpressionBinder<bool>
{
    public ComparisonBinder(TSource source, Expression<Func<TSource, bool>> propertyLambda, TValue comparisonValue) :base(null,null)
    {
         var propertyInfo = GetPropertyInfo<TSource,bool>(source, propertyLambda);
         this.Getter = () => comarisonValue.Equals((TValue)propertyInfo.GetValue(source));
         this.Setter = (bool value) => { if(value) propertyInfo.SetValue(source, comparisonValue); };
    }
}
class ComparisonBinder:ExpressionBinder
{
公共ComparisonBinder(t源代码,表达式propertyLambda,TValue comparisonValue):基(null,null)
{
var propertyInfo=GetPropertyInfo(来源,propertyLambda);
this.Getter=()=>comarisonValue.Equals((TValue)propertyInfo.GetValue(source));
this.Setter=(bool值)=>{if(value)propertyInfo.SetValue(source,comparisonValue);};
}
}
用法:

radioMale.DataBindings.Add("Checked", 
    new ComparisonBinder<ConfigClass, GenderEnum>(config, c => c.Gender, GenderEnum.Male), 
    "Value");
radioFemale.DataBindings.Add("Checked", 
    new ComparisonBinder<ConfigClass, GenderEnum>(config, c => c.Gender, GenderEnum.Female),
    "Value");
radioMale.DataBindings.Add(“选中”,
新的ComparisonBinder(config,c=>c.Gender,GenderEnum.Male),
“价值”);
radioFemale.DataBindings.Add(“选中”,
新的ComparisonBinder(config,c=>c.Gender,GenderEnum.Female),
“价值”);
我还没有测试它,但希望您能够修复任何错误并使用此解决方案

GetPropertyInfo():复制自

publicpropertyinfo GetPropertyInfo(
t来源:,
表达式属性(MBDA)
{
类型类型=类型(t源);
MemberExpression member=propertyLambda.Body作为MemberExpression;
if(成员==null)
抛出新ArgumentException(string.Format(
表达式“{0}”引用的是方法,而不是属性,
propertyLambda.ToString());
PropertyInfo-propInfo=成员。成员为PropertyInfo;
if(propInfo==null)
抛出新ArgumentException(string.Format(
表达式“{0}”引用的是字段,而不是属性,
propertyLambda.ToString());
if(type!=propInfo.ReflectedType&&
!type.IsSubclassOf(propInfo.ReflectedType))
抛出新ArgumentException(string.Format(
表达式{0}引用的属性不是来自类型{1},
propertyLambda.ToString(),
类型);
返回propInfo;
}

我刚刚提出了一个与此非常接近的代码。但是谢谢!我将合并这个
GetPropertyInfo
方法,因为我没有检查我应该检查的所有内容,并更新问题以供进一步参考。现在我要做双向跳跃。但这是另一个问题。。。
radioMale.DataBindings.Add("Checked", 
    new ComparisonBinder<DataClass,GenderEnum>(DataObj, (x) => x.Gender, GenderEnum.Male), "Value");
radioFemale.DataBindings.Add("Checked", 
    new ComparisonBinder<DataClass,GenderEnum>(DataObj, (x) => x.Gender, GenderEnum.Female), "Value");
class ComparisonBinder<TSource,TValue> : ExpressionBinder<bool>
{
    public ComparisonBinder(TSource source, Expression<Func<TSource, bool>> propertyLambda, TValue comparisonValue) :base(null,null)
    {
         var propertyInfo = GetPropertyInfo<TSource,bool>(source, propertyLambda);
         this.Getter = () => comarisonValue.Equals((TValue)propertyInfo.GetValue(source));
         this.Setter = (bool value) => { if(value) propertyInfo.SetValue(source, comparisonValue); };
    }
}
radioMale.DataBindings.Add("Checked", 
    new ComparisonBinder<ConfigClass, GenderEnum>(config, c => c.Gender, GenderEnum.Male), 
    "Value");
radioFemale.DataBindings.Add("Checked", 
    new ComparisonBinder<ConfigClass, GenderEnum>(config, c => c.Gender, GenderEnum.Female),
    "Value");
public PropertyInfo GetPropertyInfo<TSource, TProperty>(
    TSource source,
    Expression<Func<TSource, TProperty>> 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.ToString()));

    PropertyInfo propInfo = member.Member as PropertyInfo;
    if (propInfo == null)
        throw new ArgumentException(string.Format(
            "Expression '{0}' refers to a field, not a property.",
            propertyLambda.ToString()));

    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.ToString(),
            type));

    return propInfo;
}