Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Thanks to Oliver for getting me started I now have a solution that both supports refactoring and is type safe. It also let me implement INotifyPropertyChanged so it copes with properties being renamed.</p> <p>It’s usage looks like:</p> <pre><code>checkBoxCanEdit.Bind(c =&gt; c.Checked, person, p =&gt; p.UserCanEdit); textBoxName.BindEnabled(person, p =&gt; p.UserCanEdit); checkBoxEmployed.BindEnabled(person, p =&gt; p.UserCanEdit); trackBarAge.BindEnabled(person, p =&gt; p.UserCanEdit); textBoxName.Bind(c =&gt; c.Text, person, d =&gt; d.Name); checkBoxEmployed.Bind(c =&gt; c.Checked, person, d =&gt; d.Employed); trackBarAge.Bind(c =&gt; c.Value, person, d =&gt; d.Age); labelName.BindLabelText(person, p =&gt; p.Name); labelEmployed.BindLabelText(person, p =&gt; p.Employed); labelAge.BindLabelText(person, p =&gt; p.Age); </code></pre> <p>The person class shows how to implemented INotifyPropertyChanged in a type safe way (or <a href="https://stackoverflow.com/questions/527602/automatically-inotifypropertychanged/527840#527840">see this answer</a> for a other rather nice way of implementing INotifyPropertyChanged, <a href="http://activesharp.codeplex.com/" rel="nofollow noreferrer">ActiveSharp - Automatic INotifyPropertyChanged</a> also looks good ): </p> <pre><code>public class Person : INotifyPropertyChanged { private bool _employed; public bool Employed { get { return _employed; } set { _employed = value; OnPropertyChanged(() =&gt; c.Employed); } } // etc private void OnPropertyChanged(Expression&lt;Func&lt;object&gt;&gt; property) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(BindingHelper.Name(property))); } } public event PropertyChangedEventHandler PropertyChanged; } </code></pre> <p>The WinForms binding helper class has the meat in it that makes it all work:</p> <pre><code>namespace TypeSafeBinding { public static class BindingHelper { private static string GetMemberName(Expression expression) { // The nameof operator was implemented in C# 6.0 with .NET 4.6 // and VS2015 in July 2015. // The following is still valid for C# &lt; 6.0 switch (expression.NodeType) { case ExpressionType.MemberAccess: var memberExpression = (MemberExpression) expression; var supername = GetMemberName(memberExpression.Expression); if (String.IsNullOrEmpty(supername)) return memberExpression.Member.Name; return String.Concat(supername, '.', memberExpression.Member.Name); case ExpressionType.Call: var callExpression = (MethodCallExpression) expression; return callExpression.Method.Name; case ExpressionType.Convert: var unaryExpression = (UnaryExpression) expression; return GetMemberName(unaryExpression.Operand); case ExpressionType.Parameter: case ExpressionType.Constant: //Change return String.Empty; default: throw new ArgumentException("The expression is not a member access or method call expression"); } } public static string Name&lt;T, T2&gt;(Expression&lt;Func&lt;T, T2&gt;&gt; expression) { return GetMemberName(expression.Body); } //NEW public static string Name&lt;T&gt;(Expression&lt;Func&lt;T&gt;&gt; expression) { return GetMemberName(expression.Body); } public static void Bind&lt;TC, TD, TP&gt;(this TC control, Expression&lt;Func&lt;TC, TP&gt;&gt; controlProperty, TD dataSource, Expression&lt;Func&lt;TD, TP&gt;&gt; dataMember) where TC : Control { control.DataBindings.Add(Name(controlProperty), dataSource, Name(dataMember)); } public static void BindLabelText&lt;T&gt;(this Label control, T dataObject, Expression&lt;Func&lt;T, object&gt;&gt; dataMember) { // as this is way one any type of property is ok control.DataBindings.Add("Text", dataObject, Name(dataMember)); } public static void BindEnabled&lt;T&gt;(this Control control, T dataObject, Expression&lt;Func&lt;T, bool&gt;&gt; dataMember) { control.Bind(c =&gt; c.Enabled, dataObject, dataMember); } } } </code></pre> <p>This makes use of a lot of the new stuff in C# 3.5 and shows just what is possible. Now if only we had <a href="http://en.wikipedia.org/wiki/Hygienic_macro" rel="nofollow noreferrer">hygienic macros</a> lisp programmer may stop calling us second class citizens)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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