Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile time checking of bindings?

I am moderately new to MVVM and I understand some of the benefits of MVVM over simple code behind xaml (for example testability of the VM). We are using Caliburn Micro to perform some of the binding but that's kind of irrelevant, I could be using specific binding {binding ...} and my question would more or less remain the same.

I understand the logic that the VM should know nothing of the V if everything is done correctly, but it seems that because we are using dynamic run time binding between the V and the VM that the compiler can make no checks on the legality of each binding expression. For example if I have a UI component called UserName then Caliburn will try to bind that to a VM property called UserName at run time (similar to doing something like Value="{binding UserName}"). However if I rename my VM property or misspell the UI component name or binding expression we get no indication of a problem until run time.

It seems to me that it would be really nice to be able to tell the xaml that a UI component or page is going to be bound to a specific interface so that the compiler can do some of the work that will otherwise have to be done (and redone) by the test department (and that is me quite often).

Is there a way to tell xaml that we are binding to an interface or object type? Is there some tool that can plug into a xaml application to validate bindings?

like image 548
naskew Avatar asked Sep 10 '12 10:09

naskew


2 Answers

While the compiler does not provide support for compile time checks of XAML, you can probably achieve much the same result by writing a custom build task that instantiates each XAML file via the XAMLReader class, and then using a custom TraceListener to listen for binding errors.

Beyond that, if you are prepared to do your databinding using code, you can create bindings that reference propertynames directly. Something like the following (untested)

Binding createBinding<TProperty>(Expression<Func<TProperty>> property, object source)
{
    MemberExpression me = property.Body as MemberExpression;
    if (me == null || me.Expression != property.Parameters[0]
          || me.Member.MemberType != MemberTypes.Property) {
        throw new InvalidOperationException(
            "Now tell me about the property");
    }
    Binding b = new Binding(me.Member.Name);
    b.Source = source;

    return b;
}

// sample code
Binding b = createBinding(()=>this.FontSize, this);
textBlock1.SetBinding(TextBlock.FontSizeProperty, b);
like image 100
2 revs, 2 users 94% Avatar answered Nov 09 '22 04:11

2 revs, 2 users 94%


This post gives a concise example of how to eliminate the magic strings in your binding. It won't do compile-time type checking, but at least the compiler will catch misspellings.

Performance impact of Wpf Binding Path={x:Static <propertypath>}?

like image 28
RyanR Avatar answered Nov 09 '22 04:11

RyanR