|
|
|
Debug Databinding Issues in WPF
DataBinding is one of the most powerful features in WPF. But because it resolves the bindings at runtime and does not throw exceptions, it's sometimes hard to find the reason why the data do not appear as expected.
There are mainly two reasons:
- The DataBinding expression is invalid. Then use Trace Output to
resolve.
- The DataBinding expression is valid, but the result is not the expected. Then use a Debug Converter to resolve it.
Method 1: Trace messages in the output window
In the example, the text property of the TextBlock is bound to the property "InvalidPath" of the StackPanel - which does not exists.
<Window x:Class="DebugDataBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<StackPanel x:Name="stack">
<TextBlock Text="{Binding ElementName=stack, Path=InvalidPath}" />
</StackPanel>
</Window>
In this case the invalid databinding expression is reported by a trace message in the output window
System.Windows.Data Error: 39 : BindingExpression path error: 'InvalidPath' property not found on 'object' ''StackPanel' (Name='stack')'. BindingExpression:Path=InvalidPath; DataItem='StackPanel' (Name='stack'); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
Note: Binding to a path of a property that has NULL value is a valid expression and does not generate an error message (for e.g. binding to a property of the data context that is NULL).
Adjust the trace level (.NET 3.5 and higher)
NET3.5 has a new feature that allows you to set the level of details of trace messages to None , Low , Medium or High .
To set the trace level you have to include an extra namespace to your XAML:
<Window x:Class="DebugDataBinding.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">
<StackPanel x:Name="stack">
<TextBlock Text="{Binding ElementName=stack, Path=InvalidPath,
diag:PresentationTraceSources.TraceLevel=High}" />
</StackPanel>
</Window>
The following snipped shows how to adjust the trace level by code:
PresentationTraceSources.DataBindingSource.Listeners.Add(
new ConsoleTraceListener());
PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.All;
Method 2: Use a ValueConverter to break into the debugger
A simple trick is to write a value converter that does nothins except breaking into the debugger. All you need to do now is to add this converter to the binding expression that fails and you can easily see the values that should be bound.
/// <summary>
/// This converter does nothing except breaking the
/// debugger into the convert method
/// </summary>
public class DatabindingDebugConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
Debugger.Break();
return value;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
Debugger.Break();
return value;
}
}
To use the converter in XAML, reference the namespace of the assembly that contains the converter and add an instance of it to the resources of your window.
<Window x:Class="DebugDataBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DebugDataBinding"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<local:DatabindingDebugConverter x:Key="debugConverter" />
</Window.Resources>
<StackPanel x:Name="stack">
<TextBlock Text="{Binding ElementName=stack, Path=ActualWidth,
Converter={StaticResource debugConverter}}" />
</StackPanel>
</Window>
Last modified: 2009-06-08 08:31:10
Copyright (c) by Christian Moser, 2011.
Comments on this article
Show all comments
|
J | |
|
Commented on 23.March 2009 |
No one proofreads these articles, do they?
|
|
|
|
Christian Moser | |
|
Commented on 25.March 2009 |
No, it's just me writing and publish them. But I am anxious to provide technically correct information. If someone notices a mistake, I will correct it.
|
|
|
|
drewed | |
|
Commented on 29.March 2009 |
I believe 'J' was referring to the second bullet point of the introduction:
"The DataBinding expression is valid, but it . Then use Method 2 to resolve"
But it what?
|
|
|
|
IC | |
|
Commented on 2.April 2009 |
does "nothins" except....
|
|
|
|
Vishal | |
|
Commented on 3.June 2009 |
Need A example to bind data from sql server to controls...
|
|
|
|
Christian Moser | |
|
Commented on 5.June 2009 |
Hi Vishal,
you cannot bind data from an SQL database directly to WPF controls. You need to load the data into objects first. This is because WPF binding depends on properties. You can use LINQ to SQL, Entity Framework or Typed Datasets to nao your data in objects.
I hope this helps.
|
|
|
|
Ben | |
|
Commented on 5.June 2009 |
Another solution is to implement a trace listener that you add to the DataBindingSources TraceListenerCollection in PresentationTraceSources. You can override the TraceEvent methods implemented by the trace listener and either throw an exception or call Debugger.Break() to break into the debugger whenever a data binding error occurs.
|
|
|
|
Richard | |
|
Commented on 31.July 2009 |
Thanks ... very helpful
|
|
|
|
Elia | |
|
Commented on 28.August 2009 |
very useful
|
|
|
|
sathish | |
|
Commented on 23.September 2009 |
Is it possible to bind the XML directly?
|
|
|
|
MAF | |
|
Commented on 3.October 2009 |
Salam :)
No you can't, you can use LINQ to XML or use an instance of XmlDataProvider.
|
|
|
|
Farzad | |
|
Commented on 13.November 2009 |
very nice article
specially the second part
|
|
|
|
Ricibald | |
|
Commented on 1.December 2009 |
Another solution is to declare ExceptionValidationRule in Binding.ValidationRules. It causes all exceptions thrown in the databinding process to be reported as validation errors.
|
|
|
|
Tony Wall | |
|
Commented on 14.April 2010 |
Fantastic. You should work for MS and this should be in MSDN Library!
|
|
|
|
Ben | |
|
Commented on 8.May 2010 |
Another solution is to implement a trace listener that you add to the DataBindingSources TraceListenerCollection in PresentationTraceSources. You can override the TraceEvent methods implemented by the trace listener and either throw an exception or call Debugger.Break() to break into the debugger whenever a data binding error occurs.
|
|
|
|
Eric | |
|
Commented on 29.June 2010 |
Ricibald: Can you post an example of how this is done? Also will all this work with Silverlight 4.0?
|
|
|
|
akjoshi | |
|
Commented on 1.July 2010 |
A similar post written long back - http://www.beacosta.com/blog/?p=52
|
|
|
|
Bala | |
|
Commented on 20.July 2010 |
Hi Christian,
Could you please let me know how and where Path=ActualWidth is getting is used in the above example 2
|
|
|
|
Lily | |
|
Commented on 9.September 2010 |
Thanks a million! This helped us solve a similar problem with Silverlight 4.0. We were trying to bind an IsChecked property of a ToggleButton to an IsChecked custom DependencyProperty of a custom control.
|
|
|
|
WPF-Coder | |
|
Commented on 30.January 2011 |
Thank you very much for this cool idea. To ensure that the ValueConverter is indeed "reached", use the following data binding:
{Binding RelativeSource={RelativeSource Self},Converter={StaticResource debugConverter}}
Cheers, Ingo.
|
|
|
|
deepak | |
|
Commented on 9.February 2011 |
WOW its gud but j= "chuitya". what is that
|
|
|
|
Yossu | |
|
Commented on 22.February 2011 |
Thanks for a great tip. I had a problem with Blend though. I can use the debug converter in VS, but if I add it using the Blend interface, Blend crashes. This happens consistently with this converter, on any control. Blend behaves fine with other converters.
Any ideas? Thanks again
|
|
|
|
vv | |
|
Commented on 28.February 2011 |
i am new to wpf.i think their is no proper decoupling between code behind and design code
|
|
|
|
Allen | |
|
Commented on 23.March 2011 |
So you can leave the converter in place during development, and strip out later, use this approach where you see if a debugger is in fact attached to the process (OTHERWISE, your app halts and waits patiently for you in this routine!):
/// <summary>
/// Public method Convert(object value, Type targetType, object parameter, CultureInfo culture)
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
if (Debugger.IsAttached)
Debugger.Break();
else
Logger.DebugFormat("Binding value in {0} = {1}", "DatabindingDebugConverter::Convert", value);
return value;
}
|
|
|
|
sun | |
|
Commented on 9.June 2011 |
Do u have any tutorial on C#,asp.net,wcf,SilverLight or any of these?If not then please provide me the useful links
|
|
|
|
|
|