Note that there are some explanatory texts on larger screens.

plurals
  1. POhow to dynamically create binding proxies?
    primarykey
    data
    text
    <p>I don't know if I asked it right, but I'm kind of lost for hours, so bare with me.</p> <p>My initial problem was: I have a configuration object, which has an <code>enum</code> and I wanted to bind a bunch of <code>RadioButton</code>'s to the same property. As I see myself repeating it sometimes I tried to come up with a general solution for binding multiple items to the same property. The solution I found was to create a proxy which executes an expression. See the code below.</p> <pre><code>public enum GenderEnum { Male, Female } public class DataClass { public GenderEnum Gender { get; set; } } class ExpressionBinder&lt;T&gt; { public Func&lt;T&gt; Getter; public Action&lt;T&gt; Setter; public T Value { get { return Getter.Invoke(); } set { Setter.Invoke(value); } } public ExpressionBinder(Func&lt;T&gt; getter, Action&lt;T&gt; setter) { Getter = getter; Setter = setter; } } </code></pre> <p>I can use it this way:</p> <pre><code>radioMale.Tag = GenderEnum.Male; radioFemale.Tag = GenderEnum.Female; var proxyM = new ExpressionBinder&lt;bool&gt;( () =&gt; DataObj.Gender == (GenderEnum)radioMale.Tag, (val) =&gt; { if (val) DataObj.Gender = (GenderEnum)radioMale.Tag; }); var proxyF = new ExpressionBinder&lt;bool&gt;( () =&gt; DataObj.Gender == (GenderEnum)radioFemale.Tag, (val) =&gt; { if (val) DataObj.Gender = (GenderEnum)radioFemale.Tag; }); radioMale.DataBindings.Add("Checked", proxyM, "Value"); radioFemale.DataBindings.Add("Checked", proxyF, "Value"); </code></pre> <p>It's just an example, I wanted to keep it simple. But this approach actually <strong>WORKS</strong>. By question is:</p> <p>I want to encapsulate the comparison and set expressions inside a derived class. </p> <pre><code>class ComparisonBinder : ExpressionBinder {} </code></pre> <p>Unfortunately, I can only say how I would like to use it.</p> <pre><code>radioMale.DataBindings.Add("Checked", new ComparisonBinder&lt;ConfigClass&gt;((c) c.Gender, GenderEnum.Male), "Value"); radioFemale.DataBindings.Add("Checked", new ComparisonBinder&lt;ConfigClass&gt;((c) c.Gender, GenderEnum.Female), "Value"); </code></pre> <p>So, how would you implement this? Feel free to change my ExpressionBinder class if you need to.</p> <hr> <hr> <p><strong>The Final code</strong></p> <p>(edited again: you can't omit the TValue parameter using object type. During the conversion of the lambda expression the compiler will add a call to <code>Convert()</code>.)</p> <pre><code>class ComparisonBinder&lt;TSource, TValue&gt; : ExpressionBinder&lt;bool&gt; { private TSource instance; private TValue comparisonValue; private PropertyInfo pInfo; public ComparisonBinder(TSource instance, Expression&lt;Func&lt;TSource, TValue&gt;&gt; property, TValue comparisonValue) { 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); } } /// &lt;summary&gt; /// Adapted from surfen's answer (http://stackoverflow.com/a/10003320/219838) /// &lt;/summary&gt; private PropertyInfo GetPropertyInfo(Expression&lt;Func&lt;TSource, TValue&gt;&gt; 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 &amp;&amp; !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; } } </code></pre> <p><strong>Usage:</strong></p> <pre><code>radioMale.DataBindings.Add("Checked", new ComparisonBinder&lt;DataClass,GenderEnum&gt;(DataObj, (x) =&gt; x.Gender, GenderEnum.Male), "Value"); radioFemale.DataBindings.Add("Checked", new ComparisonBinder&lt;DataClass,GenderEnum&gt;(DataObj, (x) =&gt; x.Gender, GenderEnum.Female), "Value"); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload