Bei der WinForms-Entwicklung werden Bindings wie folgt definiert:
public interface IPersonViewModel {
string Name { get; set; }
}
public partial class Form1 : Form, IPersonView {
private IPersonViewModel _viewModel;
public void BindToViewModel(IPersonViewModel viewModel) {
_viewModel = viewModel;
Binding binding = new Binding(“Text”, _viewModel, “Name”);
nameTextBox.Bindings.Add(binding);
}
}
Das ganze funktioniert soweit problemlos.
Allerdings gibt es zwei “Schönheitsfehler”:
- Hat man Tippfehler im Namen der Property (hier “Text”) oder im Namen des DataMembers (hier “Name”), fällt das erst zur Laufzeit infolge einer Exception auf
- Refaktorisiert man das Model, bekommt das Binding davon nichts mit – Resultat: siehe 1.
Mithilfe der folgenden ExtensionMethod kann man beide Probleme elegant umschiffen:
public static void SetBinding<TModel>(this Control control, Control childControl,
Expression<Func<Control, object>> property, TModel model,
Expression<Func<TModel, object>> dataMember) {
Expression propertyBody = property.Body;
Expression dataMemberBody = dataMember.Body;
if (ExpressionType.MemberAccess == propertyBody.NodeType && ExpressionType.MemberAccess == dataMemberBody.NodeType) {
MemberExpression propertyMemberExpression = propertyBody as MemberExpression;
MemberExpression dataMemberExpression = dataMemberBody as MemberExpression;
Binding binding = new Binding(propertyMemberExpression.Member.Name, model, dataMemberExpression.Member.Name);
childControl.DataBindings.Add(binding);
}
if (ExpressionType.MemberAccess == propertyBody.NodeType && ExpressionType.Convert == dataMemberBody.NodeType) {
MemberExpression propertyMemberExpression = propertyBody as MemberExpression;
UnaryExpression unaryExpression = dataMemberBody as UnaryExpression;
MemberExpression dataMemberExpression = unaryExpression.Operand as MemberExpression;
Binding binding = new Binding(propertyMemberExpression.Member.Name, model, dataMemberExpression.Member.Name);
childControl.DataBindings.Add(binding);
}
}
Aufruf innerhalb der Form oder eines UserControls:
this.SetBinding<IPersonViewModel>(nameTextBox, textbox => textbox.Text, _viewModel, model => model.Name);
Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war, bitte "kicken" sie ihn.
