Posts
17
Comments
1844
Trackbacks
18
giovedì 3 aprile 2008
Find databinding mistakes using PresentationTracesources.TraceLevel in Fx 3.5

Debugging WPF databinding problems can be sometimes a painful experience: consider this simple XAML fragment and its codebehind that doesn’t work due to mistakenly typed CustomerName inside binding expression.

<Window x:Class="WPF_Databind.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml             
    Title="Window1" Height="300" Width="00">
    <Grid>
        <TextBox 
            Text="{Binding Path=CustomerName}"
            Height="23" Margin="87,65,71,0" Name="textBox1" VerticalAlignment="Top" />
    </Grid>
</Window>

 

namespace WPF_Databind { public partial class Window1 : Window { public Window1 () { InitializeComponent(); this.DataContext = new Customer() { Name = "Foo", Id = 42 }; } } public class Customer { public string Name { get; set; } public int Id { get; set; } } }

Running this sample results in an empty Textbox: how do we get hints about what’s wrong with it? , the only place where we can look for a possible reason is Visual Studio output window (see below) and among various output messages search for some useful information like:

System.Windows.Data Error: 35 : BindingExpression path error: 'CustomerName' property not found on 'object' ''Customer' (HashCode=22613453)'. BindingExpression:Path=CustomerName; DataItem='Customer' (HashCode=22613453); target element is 'TextBox' (Name='textBox1'); target property is 'Text' (type 'String')

In some cases this wouldn’t help you much and you’d like to have more details about what’s wrong with your databinding, well starting from .NET Framework 3.5 you can thanks to PresentationTraceSources class.
Let’s modify our previous sample importing System.Diagnostics namespace (that’s where PresentationTraceSources lives even if hosted inside WindowsBase assembly) and applying it to our failing binding.

<Window x:Class="WPF_Databind.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"                
    Title="Window1" Height="300" Width="300">
    <Grid>
        <TextBox 
            Text="{Binding Path=CustomerName,diag:PresentationTraceSources.TraceLevel=High}"
            Height="23" Margin="87,65,71,0" Name="textBox1" VerticalAlignment="Top" />
    </Grid>
</Window>

Running sample again we can see a more verbose description of what really happens behind our binding:

System.Windows.Data Warning: 47 : Created BindingExpression (hash=14421545) for Binding (hash=33163964)
System.Windows.Data Warning: 49 : Path: 'CustomerName'
System.Windows.Data Warning: 51 : BindingExpression (hash=14421545): Default mode resolved to TwoWay
System.Windows.Data Warning: 52 : BindingExpression (hash=14421545): Default update trigger resolved to LostFocus
System.Windows.Data Warning: 53 : BindingExpression (hash=14421545): Attach to System.Windows.Controls.TextBox.Text (hash=35567111)System.Windows.Data Warning: 58 : BindingExpression (hash=14421545): Resolving source
System.Windows.Data Warning: 61 : BindingExpression (hash=14421545): Found data context element: TextBox (hash=35567111) (OK)
System.Windows.Data Warning: 62 : BindingExpression (hash=14421545): DataContext is null
System.Windows.Data Warning: 56 : BindingExpression (hash=14421545): Resolve source deferred
'WPF_Databind.vshost.exe' (Managed): Loaded 'C:\Windows\assembly\GAC_MSIL\PresentationFramework.Aero\3.0.0.0__31bf3856ad364e35\PresentationFramework.Aero.dll'
System.Windows.Data Warning: 58 : BindingExpression (hash=14421545): Resolving source
System.Windows.Data Warning: 61 : BindingExpression (hash=14421545): Found data context element: TextBox (hash=35567111) (OK)
System.Windows.Data Warning: 69 : BindingExpression (hash=14421545): Activate with root item Customer (hash=1669504)
System.Windows.Data Warning: 98 : BindingExpression (hash=14421545): At level 0 - for Customer.CustomerName found accessor <null>
System.Windows.Data Error: 35 : BindingExpression path error: 'CustomerName' property not found on 'object' ''Customer' (HashCode=1669504)'. BindingExpression:Path=CustomerName; DataItem='Customer' (HashCode=1669504); target element is 'TextBox' (Name='textBox1'); target property is 'Text' (type 'String')
System.Windows.Data Warning: 71 : BindingExpression (hash=14421545): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 77 : BindingExpression (hash=14421545): TransferValue - using fallback/default value ''
System.Windows.Data Warning: 78 : BindingExpression (hash=14421545): TransferValue - using final value ''

Available values for TraceLevel property are None,Low, Medium and High which result in different tracing details, and of course, don’t forget to remove it before releasing the application.

Note for Expression Blend users
It looks like that both Expression Blend 2.0 and 2.5 don’t recognize TraceLevel property so you won’t be able to see the artboard in presence of this attibute, but this will certainly be fixed in future releases.

posted @ giovedì 3 aprile 2008 8.58 | Feedback (788)
News

This is my personal blog.
These postings are provided "AS IS" with no warranties, and confer no rights.

Disciple