Binding error wpf

Technical articles, content and resources for IT Professionals working in Microsoft technologies

This article covers many techniques you can use to troubleshoot and debug your WPF application, including binding errors, exception handling, inspecting the VisualTree and logging.

Table of Contents

  • Introduction
  • Binding Errors
    • 1. Changing Trace Level for All in Options
    • 2. Changing Trace Level on a Specific Binding
  • WPF Tree Visualizer
    • Other inspection tools
  • Debuging Your Code
  • Inner Exceptions
  • Unhandled Exceptions
    • Application.DispatcherUnhandledException
    • AppDomain.CurrentDomain.UnhandledException
    • TaskScheduler.UnobservedTaskException
    • The catch-all Unhandled Handler!
    • Drilling down to include the Inner Exceptions
  • Commenting Out and Binary Chopping
  • Is It Reproducable?
  • Logging
    • Logging Level
    • Repository Choice
    • Why Reinvent the Wheel
      • Log4Net
      • ELMAH
      • NLog
      • NuGet
  • See Also
  • Community Resources

Introduction

Windows Presentation Foundation (WPF) is a joy to develop rich user experiences with. Animations, bindings, reskinnable codeless interfaces, all backed up with traditional .Net programming all make for a very rapid development cycle. However, when something
goes wrong in that autogenerated super-sexy front-end, it is not always clear where the problem is.

This article will cover some of the methods for analyzing your WPF application, troubleshooting issues, and debugging seemingly obscure errors. 


Return to Top


Binding Errors

When an error occurs in the binding framework, the notification is usually «silent», in that is doesn’t pop up an error dialog to the user. The error is instead displayed in the
Output Window of Visual Studio. Although the errors seem obscure at first, there are only a few common ones and they are quite helpful messages. 

Below are some typical errors and an explanation for each. 

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression:Path=PartIds; DataItem=null; target element is 'ComboBox'
(Name=''); target property is 'ItemsSource' (type 'IEnumerable')

This is a ComboBox inside a DataGridTemplateColumn. I am binding its ItemsSource to a property called PartIds. 

It is erroring when looking for the binding source, in other words the physical object to find the property on.

In this example, the error was because the source is a Window, not a UserControl. 

"System.Windows.Data Error: 40 : BindingExpression path error: 'MyStringOptionz' property not found on 'object' ''MainWindow' (Name='Window')'. BindingExpression:Path=MyStringOptionz; DataItem='MainWindow' (Name='Window'); target element is 'ComboBox'
(Name=''); target property is 'ItemsSource' (type 'IEnumerable')"

This is when the property name in the binding expression is wrong, or the property does not exist in the source object.

In this example, the property name was misspelled with a ‘z’.

Sometimes you will need a more detailed debugging output for binding. There are two ways to do this.

1. Changing Trace Level for All in Options

Click the Visual Studio menu Tools / Options, then open
Debugging and Output Window. In there you can change the
DataBinding output settings to Verbose or
All
.

(click to enlarge)

2. Changing Trace Level on a Specific Binding

If you increase the trace level that way, you will get a WHOLE LOAD of messages for everything. Far better to target the specific binding where the error is. To do this, you can call on an Attached Property PresentationSources.TraceLevel and set it for just
the one binding.

<ComboBox
ItemsSource="{Binding PartIdz,
PresentationTraceSources.TraceLevel=High
, RelativeSource={RelativeSource AncestorType=Window}}"
. . . />

For more information on the Trace Levels and what they represent,
read here. 


Return to Top


WPF Tree Visualizer

The WPF Tree Visualizer comes built into Visual Studio, and is an essential tool to know about.

With it, you can break into the Visual Tree and inspect the actual generated elements and their properties.

To use a Visualizer, you click on the magnifying glass next to a variable name in
DataTips, a Watch window, or in the
Autos, Locals, or
Quick Watch
window.

If you are visualizing a string object for example, you get a big grey text window. However, if you visualize a FrameworkElement, you get the WPF Tree Visualizer.

(click to enlarge) 

For a Quick Start on how to use the WPF TV, try this :
Debugging WPF — WPF Tree Visualizer + Helper Class

It also supplies a handy Attached Property you can drop in anywhere, without messing your code. 

The WPF Tree Visualizer is great for inspecting the VisualTree, but if you want to
change any of the properties, you have to look at the «Locals» tab, as shown below.

(click to enlarge)

Other inspection tools

WPF Tree Visualizer is usually enough for the experienced developer to find the problem, however there are plenty of tools around if you prefer to defer.

  • WPF Inspector
  • UI Spy (in Microsoft Windows SDK)
  • Snoop
  • XamlIT
  • Mole
  • Pistachio


Return to Top


Debuging Your Code

Apart from the WPF Tree Visualiser, the debugger in WPF applications is the main way to break into your application, trace through and follow program execution to the point of failure.

This is all standard Visual Studio stuff, and I won’t waste time here reproducing what is available elsewhere:

  • Debugging in Visual Studio
  • Debugging Managed Code
  • Debugging, Tracing, and Profiling


Return to Top


Inner Exceptions

When your application raises an exception, and you are debugging in Visual Studio, you get the usual error dialog with the details. However, when the error is a XAML error, it is most frequently buried deeper in the exception details.

Within each exception is an Inner Exception, which is just another exception, but from a layer further down. If XAML throws an error about a missing resource, it re-raises the error as a meaningless «XAML Markup error». When you drill down deeper, you find
what resource the actual error relates to.

Josh Smith wrote best documents the joy of inner exceptions  here. 


Return to Top


Unhandled Exceptions

It is impossible to protect against every possible fault that could happen, when your application is «out in the wild». 

There are however, ways to try and improve on the standard Windows error dialogue, and stack dump, which will help you find the fault.

When an exception is unhandled by your application, there are several Unhandled Exception events that you can tap into and handle.

You can download and test all five handlers here :
Handling Unhandled Exceptions in WPF (The most complete collection of handlers)

Application.DispatcherUnhandledException

This is triggered when the UI thread causes an unhandled exception. You can attach a handler to it either in App.xaml

<Application
x:Class="MyProject.App"

  StartupUri="MainWindow.xaml"
DispatcherUnhandledException="App_DispatcherUnhandledException">

 <Application.Resources
/>

</Application>

… or App.xaml.cs

namespace
MyProject

{

 public
partial
class
App : Application

 {

  public
App()

  {

   DispatcherUnhandledException +=
new
System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);

  }

What you get in the handler arguments is a standard exception. Handle as you like, preferably write it to a permissions safe file location.

You can also set e.Handled to true if you want to try to overcome the error and move on

void
App_DispatcherUnhandledException(object
sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)

{

 ProcessError(e.Exception);

 e.Handled =
true;

}

 

Sometimes the error is too severe, and your application still crashes. But at least you have hopefully captured something useful, before it did.

AppDomain.CurrentDomain.UnhandledException

If the error is not on the UI thread, then the previous handler won’t catch it. It is solely for the Dispatcher thread. To capture errors on any other thread, you need this second one.

This handler is attached in the Startup event handler, which can again be hooked into from mark-up:

<Application
x:Class="UnhandledExceptionHandler.App"

  StartupUri="MainWindow.xaml"
Startup="App_Startup">

 <Application.Resources
/>

</Application>

… or in code:

namespace
MyProject

{

 public
partial
class
App : Application

 {

  public
App()

  {

   Startup +=
new
StartupEventHandler(App_Startup);

  }

  void
App_Startup(object
sender, StartupEventArgs e)

  {

   AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

  }

  void
CurrentDomain_UnhandledException(object
sender, UnhandledExceptionEventArgs e)

  {

   var exception = e.ExceptionObject
as
Exception;

   ProcessError(exception);

   if
(e.IsTerminating)

  MessageBox.Show("Goodbye world!");

  }

Notice this uses an ExceptionObject, which is derived from Exception, so we can simply cast it back, for a generic exception handler, as shown below.

Also notice the ExceptionObject has an IsTerminating flag.

TaskScheduler.UnobservedTaskException

This exception happens when a Task has an «unobserved exception», and is about to trigger the «exception escalation policy», which by default
terminates the process.

namespace
MyProject

{

 public
partial
class
App : Application

 {

  public
App()

  {

   TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

  }

Again, we can try to prevent crashing, in this case by calling the e.SetObserved method, which marks the exception as «observed» and prevents exception escalation towards a termination (crash). 

void
TaskScheduler_UnobservedTaskException(object
sender, UnobservedTaskExceptionEventArgs e)

{

 ProcessError(e.Exception);

 e.SetObserved();

}

 

The catch-all Unhandled Handler!

Putting those three handlers together, we get the following:

namespace
MyProject

{

 public
partial
class
App : Application

 {

  public
App()

  {

   DispatcherUnhandledException += App_DispatcherUnhandledException;

   TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

   Startup +=
new
StartupEventHandler(App_Startup);

  }

  void
App_Startup(object
sender, StartupEventArgs e)

  {

   AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

  }

 

In the examples below, I show how to try and mark the exceptions as handled/observed, and continue execution. However, you may just want to close «gracefully», with a polite message, instead of an all-out crash.

One thing is certain, you will probably want a unified way of handling the exceptions, wherever they come from, as shown below.

Drilling down to include the Inner Exceptions

As mentioned before, the real reason for an error could be buried several layers down in Inner Exceptions. The three handlers above shared one error logging method, shown below, which iterates down till there are no more Inner Exceptions.

private
void
ProcessError(Exception exception)

{

 var error =
"Exception = "
+ exception.Message;

 while(exception.InnerException !=
null)

 {

  exception = exception.InnerException;

  error +=
" : Inner Exception = "
+ exception.Message;

 }

 //This is where you save to file.

 MessageBox.Show(error);

}

 

Early attention to error handling in your application will always help production, because most bugs occur during development.

See Logging below.


Return to Top


Commenting Out and Binary Chopping

If a bug in your application is being particularly hard to find, there may be only one way left to find the culprit. It’s very simple, and is often simply the fastest way to drill down to the offender.

The method is simply to remove (or comment out) sections of your code, or XAML, until you get execution PAST the error.

Then you start replacing parts of the removed code, until you find the exact control or method that is causing the problem.

It is referred to as binary chopping because you cut the code into two, to get past the error, then in two again, replacing half of the removed code, and so on until you get down to the offending code/xaml.

You can comment out huge chunks of your code or markup in Visual Studio with ctrl-k + c, then ctrl-k + u to uncomment. Both functions also available in the edit / advanced menu.

This is one of the advantages of writing your application to the MVVM design pattern. MVVM separates your UI (View) from the business logic supplied by the ViewModel, or the Model itself. This means the View is much more loosely coupled, and there are no
hooks from code-behind, acting directly on controls, like referring to controls by name (x:Name) like MyTextBox.Text = «hello». In MVVM the emphasis is all on the bindings, so commenting out half your XAML just means less binding requests, and commenting out
half your code/properties means more binding errors, but not a crash. 

Even an MVVM setup can have problems when you try to comment out half the markup. Controls may be relying on other controls, with direct biding in XAML. So there is always a certain amount of «knock-on» effects that also need commenting out, but experience
often shows it is quite simply a very fast and effective way to find the sinner.

Just make sure you keep a copy of the original file (or have recently committed your code to source control) before such dramatic actions. Just in case you make an edit that looses your comment/cut history ;)


Return to Top


Is It Reproducable?

When you hit a brick wall, many people turn to the
MSDN forums, for help and advice from other developers. Often, just the act of trying to put a problem into words for others to understand is equivalent to having a colleague look over your shoulder, which often catches those obvious «too close to the trees»
kind of mistakes that we all make.

However, if the problem isn’t obvious from your description, you will get a much quicker and accurate response from the forum if you supply a
reproduceable example of your problem in a few code snippets.

Quite often, when you try to reproduce the problem in a new project, you will often find the culpret anyway! 


Return to Top


Logging

The other age old method of tracing bugs in your application, both in development and once released, is to keep a log of messages from every notable step of your application.

If your bug is of a composite nature (comprising of several different causes), or developing after several iterations, or at an unknown point, you will need to build a picture of what is happening, before you can even know where to start. 

Logging Level

Writing comments and session data to a log file means scattering «WriteToLog» type methods throughout your code. It is therefore common to build a «LogLevel» parameter into your methods, allowing you to control the amount of spam that gets written. In a
published application you would only want to capture critical messages, but with a config file flag or startup parameter that allows you to crank up the debug logging (logging ALL messages), for a client that experiences a bug. 

Repository Choice

A log repository can be anything from a text file, to a database. One word of caution however. It is no good logging errors to a database if it was a database connection error. So file based logging for critical errors is strongly advised. Then you simply
have a check method on application startup, for any waiting critical error files, that may have been generated when the application crashed. You can then ‘process’ them (into a database, or send by email) and then delete.

It is as explained, quite simple to create your own logging architecture for your application. The key to success is to START EARLY! Don’t try to strap error handling or logging on later, as it will never be as useful as if you had started from the outset.
Also, the majority of bugs are caused during development anyway, so early attention to error handling and logging may take slightly longer to code, but will help speed up the overall production process. 

Why Reinvent the Wheel

You could have a lot of fun building your own error logging framework, that is thread safe and foolproof. Or if you’re pushed for time or more interested in higher things, why not just adopt a tried and tested logging framework. Here are some options, but
you should shop around, as new kids often come on the block. 

Log4Net

One of the most established frameworks. «log4net is a tool to help the programmer output log statements to a variety of output targets. In case of problems with an application, it is helpful to enable logging so that
the problem can be located. With log4net it is possible to enable logging at runtime without modifying the application binary. The log4net package is designed so that log statements can remain in shipped code without incurring a high performance cost. It follows
that the speed of logging (or rather not logging) is crucial. At the same time, log output can be so voluminous that it quickly becomes overwhelming. One of the distinctive features of log4net is the notion of hierarchical loggers. Using these loggers it is
possible to selectively control which log statements are output at arbitrary granularity. log4net is designed with two distinct goals in mind: speed and flexibility»
 

ELMAH

A very popular framework. «Stands for Logging Modules and Handlers. An application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications
on a machine, without any need for re-compilation or re-deployment.»
 

NLog

Newer but 3rd popular «A logging platform for .NET with rich log routing and management capabilities. It can help you produce and manage high-quality logs for your application regardless of its size or complexity.»

NuGet

All of the above frameworks are available through NuGet. If you don’t already have NuGet, it is like an App store for Visual Studio application development. If you want a logging framework, or an MVVM framework, simply open the package manager and search.
Results are listed by popularity. Click to install, and the package gets downloaded and integrated into your current project. That means all the dlls are added and registered, and any supporting files are added to your project. It takes all the pain out of
adding supporting packages to your project. This is a must for all developers. No excuses, get it now! 


Return to Top


See Also

  • Troubleshooting Portal
  • See routed events article
    http://code.msdn.microsoft.com/silverlight/WPFSilverlight-Routed-49a16914

 ↑
Return to Top


Community Resources

  • Debugging WPF — WPF Tree Visualizer + Helper Class
  • How to: Use the WPF Tree Visualizer
  • How to: Display WPF Trace Information
  • Trees in WPF
  • Breakpoints
  • Locals Window
  • Threads Window
  • Output Window
  • Exception.InnerException Property
  • Application.DispatcherUnhandledException Event
  • AppDomain.UnhandledException Event
  • Dispatcher.UnhandledException Event
  • Tips on how to debug and learn about WPF
  • WPF performance Suite (in Windows SDK)
  • UI Spy (in Windows SDK)
  • Spy++
  • StyleSnooper
  • Optimizing WPF Application Performance
  • Debugging Tools (.NET Framework)
  • Debugging in Visual Studio
  • Debugging Managed Code
  • Debugging, Tracing, and Profiling 


Return to Top


I was also going to recommend Bea Stollnitz’s article but Jonathan Allen got his post in while I was still typing this one. I also recommend the links in this blog entry.

In this particular case you can see that somewhere a ListBoxItem has a FindAncestor binding to an ItemsControl that is failing. That tells you right away there is a ListBoxItem somewhere that is either:

  1. Not in the visual tree, or
  2. Not under an ItemsControl (a ListBox is an ItemsControl)

In addition, you know that someone, somewhere, is binding a ListBoxItem’s VerticalContentAlignment property to FindAncestor.

Looking at the system themes (shipped with Expression Blend and also available through NET Reflector’s BAMLViewer Add-in), we see this:

<Style x:Key="{x:Type ListBoxItem}">
  <Setter Property="VerticalContentAlignment"
          Value="{Binding Path=VerticalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}" />

This explains where the binding comes from. The next question is, how is a ListBoxItem being created that is not under a ListBox (or other ItemsControl)?

Some things to look for:

  • Are you constructing ListBoxItems in code anywhere?
  • Is there any ListBoxItem explicitly specified in your XAML?
  • Do you have any code that manually manipulates the items in ListBox?

Hopefully this will head you in the right direction.

Data binding:

Since data bindings are evaluated at runtime, and no exceptions are thrown when they fail, a bad binding can sometimes be very hard to track down. These
problems can occur in several different situations, but a common issue is when you try to bind to a property that doesn’t exist, either because you
remembered its name wrong or because you simply misspelled it. Here’s an example:

<Window x:Class="WpfTutorialSamples.DataBinding.DataBindingDebuggingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataBindingDebuggingSample" Height="100" Width="200">
    <Grid Margin="10" Name="pnlMain">
		<TextBlock Text="{Binding NonExistingProperty, ElementName=pnlMain}" />
	</Grid>
</Window>

The Output window

The first place you will want to look is the Visual Studio Output window. It should be at the bottom of your Visual Studio window, or you can activate it
by using the [Ctrl+Alt+O] shortcut. There will be loads of output from the debugger, but somewhere you should find a line like this, when running the above
example:


System.Windows.Data Error: 40 : BindingExpression path error: ‘NonExistingProperty’ property not found on ‘object’ »Grid’ (Name=’pnlMain’)’.
BindingExpression:Path=NonExistingProperty; DataItem=’Grid’ (Name=’pnlMain’); target element is ‘TextBlock’ (Name=»); target property is ‘Text’ (type
‘String’)

This might seem a bit overwhelming, mainly because no linebreaks are used in this long message, but the important part is this:

‘NonExistingProperty’ property not found on ‘object’ »Grid’ (Name=’pnlMain’)’.

It tells you that you have tried to use a property called «NonExistingProperty» on an object of the type Grid, with the name pnlMain. That’s actually
pretty concise and should help you correct the name of the property or bind to the real object, if that’s the problem.

Adjusting the trace level

The above example was easy to fix, because it was clear to WPF what we were trying to do and why it didn’t work. Consider this next example though:

<Window x:Class="WpfTutorialSamples.DataBinding.DataBindingDebuggingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataBindingDebuggingSample" Height="100" Width="200">
    <Grid Margin="10">
		<TextBlock Text="{Binding Title}" />
	</Grid>
</Window>

I’m trying to bind to the property «Title», but on which object? As stated in the article on data contexts, WPF will use the DataContext property on the
TextBlock here, which may be inherited down the control hierarchy, but in this example, I forgot to assign a data context. This basically means that I’m
trying to get a property on a NULL object. WPF will gather that this might be a perfectly valid binding, but that the object just hasn’t been initialized
yet, and therefore it won’t complain about it. If you run this example and look in the Output window, you won’t see any binding errors.

However, for the cases where this is not the behavior that you’re expecting, there is a way to force WPF into telling you about all the binding problems it
runs into. It can be done by setting the TraceLevel on the PresentationTraceSources object, which can be found in the System.Diagnostics namespace:

<Window x:Class="WpfTutorialSamples.DataBinding.DataBindingDebuggingSample"
        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="DataBindingDebuggingSample" Height="100" Width="200">
    <Grid Margin="10">
		<TextBlock Text="{Binding Title, diag:PresentationTraceSources.TraceLevel=High}" />
	</Grid>
</Window>

Notice that I have added a reference to the System.Diagnostics namespace in the top, and then used the property on the binding. WPF will now give you loads
of information about this specific binding in the Output window:

System.Windows.Data Warning: 55 : Created BindingExpression (hash=2902278) for Binding (hash=52760599)
System.Windows.Data Warning: 57 :   Path: 'Title'
System.Windows.Data Warning: 59 : BindingExpression (hash=2902278): Default mode resolved to OneWay
System.Windows.Data Warning: 60 : BindingExpression (hash=2902278): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 61 : BindingExpression (hash=2902278): Attach to System.Windows.Controls.TextBlock.Text (hash=18876224)
System.Windows.Data Warning: 66 : BindingExpression (hash=2902278): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=2902278): Found data context element: TextBlock (hash=18876224) (OK)
System.Windows.Data Warning: 70 : BindingExpression (hash=2902278): DataContext is null
System.Windows.Data Warning: 64 : BindingExpression (hash=2902278): Resolve source deferred
System.Windows.Data Warning: 66 : BindingExpression (hash=2902278): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=2902278): Found data context element: TextBlock (hash=18876224) (OK)
System.Windows.Data Warning: 70 : BindingExpression (hash=2902278): DataContext is null
System.Windows.Data Warning: 66 : BindingExpression (hash=2902278): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=2902278): Found data context element: TextBlock (hash=18876224) (OK)
System.Windows.Data Warning: 70 : BindingExpression (hash=2902278): DataContext is null
System.Windows.Data Warning: 66 : BindingExpression (hash=2902278): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=2902278): Found data context element: TextBlock (hash=18876224) (OK)
System.Windows.Data Warning: 70 : BindingExpression (hash=2902278): DataContext is null
System.Windows.Data Warning: 66 : BindingExpression (hash=2902278): Resolving source  (last chance)
System.Windows.Data Warning: 69 : BindingExpression (hash=2902278): Found data context element: TextBlock (hash=18876224) (OK)
System.Windows.Data Warning: 77 : BindingExpression (hash=2902278): Activate with root item <null>
System.Windows.Data Warning: 105 : BindingExpression (hash=2902278):   Item at level 0 is null - no accessor
System.Windows.Data Warning: 79 : BindingExpression (hash=2902278): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 87 : BindingExpression (hash=2902278): TransferValue - using fallback/default value ''
System.Windows.Data Warning: 88 : BindingExpression (hash=2902278): TransferValue - using final value ''

By reading through the list, you can actually see the entire process that WPF goes through to try to find a proper value for your TextBlock control.
Several times you will see it being unable to find a proper DataContext, and in the end, it uses the default {DependencyProperty.UnsetValue} which
translates into an empty string.

Using the real debugger

The above trick can be great for diagnosing a bad binding, but for some cases, it’s easier and more pleasant to work with the real debugger. Bindings
doesn’t natively support this, since they are being handled deep inside of WPF, but using a Converter, like shown in a previous article, you can actually
jump into this process and step through it. You don’t really need a Converter that does anything useful, you just need a way into the binding process, and
a dummy converter will get you there:

<Window x:Class="WpfTutorialSamples.DataBinding.DataBindingDebuggingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:self="clr-namespace:WpfTutorialSamples.DataBinding"
        Title="DataBindingDebuggingSample" Name="wnd" Height="100" Width="200">
	<Window.Resources>
		<self:DebugDummyConverter x:Key="DebugDummyConverter" />
	</Window.Resources>
    <Grid Margin="10">
		<TextBlock Text="{Binding Title, ElementName=wnd, Converter={StaticResource DebugDummyConverter}}" />
	</Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Data;
using System.Diagnostics;

namespace WpfTutorialSamples.DataBinding
{
	public partial class DataBindingDebuggingSample : Window
	{
		public DataBindingDebuggingSample()
		{
			InitializeComponent();
		}
	}

	public class DebugDummyConverter : IValueConverter
	{
		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			Debugger.Break();
			return value;
		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			Debugger.Break();
			return value;
		}
	}
}

In the Code-behind file, we define a DebugDummyConverter. In the Convert() and ConvertBack() methods, we call Debugger.Break(), which has the same effect
as setting a breakpoint in Visual Studio, and then return the value that was given to us untouched.

In the markup, we add a reference to our converter in the window resources and then we use it in our binding. In a real world application, you should
define the converter in a file of its own and then add the reference to it in App.xaml, so that you may use it all over the application without having to
create a new reference to it in each window, but for this example, the above should do just fine.

If you run the example, you will see that the debugger breaks as soon as WPF tries to fetch the value for the title of the window. You can now inspect the
values given to the Convert() method, or even change them before proceeding, using the standard debugging capabilities of Visual Studio.

If the debugger never breaks, it means that the converter is not used. This usually indicates that you have an invalid binding expression, which can be
diagnosed and fixed using the methods described in the start of this article. The dummy-converter trick is only for testing valid binding expressions.

This article has been fully translated into the following languages:

  • Bulgarian

  • Chinese

  • Danish

  • French

  • German

  • Italian

  • Japanese

  • Polish

  • Portuguese

  • Russian

  • Spanish

  • Swedish

  • Vietnamese

Is your preferred language not on the list? Click here to help us translate this article into your language!


  • Remove From My Forums
  • Question

  • Hi,

    We are using the MVVM pattern in our WPF applications, and I’d like to know if there is some way to make the app crash or receive some kind of runtime error when having binding errors when executing a WPF application.

    I know it is possible to check the output window in Visual Studio to read the errors, but I’d like to have a more noticable kind of error if possible.

    Thank you very much,

    Igor.


    Igor

Answers

    • Marked as answer by

      Wednesday, February 3, 2010 5:04 AM

  • Hi Igor,

    As far as I know, you can set ValidatesOnExceptions of the Binding object to true, and when there are exceptions occured, it will be added to Validation.Errors. This way does not force the app to crash, but may indicate you that exception is thrown by binding. Here is an article might help you understand—-Handling and Reporting WPF Data Binding Validation Errors and Exceptions

    If your purpose is only to help assist debugging the binding errors in the application, there are typically ways other than checking out the output window of Visual Studio. You can check out this article for more information.

    Best regards,
    Bruce Zhou


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.

    • Marked as answer by
      Bruce.Zhou
      Friday, December 4, 2009 1:39 AM

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

1
branch

2
tags

Code

  • Use Git or checkout with SVN using the web URL.

  • Open with GitHub Desktop

  • Download ZIP

Latest commit

Files

Permalink

Failed to load latest commit information.

Type

Name

Latest commit message

Commit time

Turn WPF binding errors into exceptions

A lightweight library that converts WPF binding errors into exceptions, so you can quickly spot errors in the XAML markup and detect them unit tests.

Exception shown in Visual Studio

All it requires is a single line in your existing code:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs args)
    {
        base.OnStartup(args);
        
        // Start listening for WPF binding error.
        // After that line, a BindingException will be thrown each time
        // a binding error occurs.
        BindingExceptionThrower.Attach();
    }
}

Installing:

With .NET CLI

> dotnet add package WpfBindingErrors

With Package Manager:

PM> Install-Package WpfBindingErrors

https://www.nuget.org/packages/WpfBindingErrors

Content

  1. Project WpfBindingError is a reusable assembly that listens for binding errors.
  2. Project SampleWpfApplication shows how to throw BindingException at runtime.
  3. Project SampleWpfApplicationTests shows how to check binding errors in a unit test project.

Each project contains a dedicated README with more detail.

Supported frameworks

  • .NET Core 3.0 🆕
  • .NET Framework 4.6
  • .NET Framework 4.5.2
  • .NET Framework 4.5.1
  • .NET Framework 4.5
  • .NET Framework 4.0

Contributors

  • Gareth Brown
  • Bruno Juchli

Data binding establishes a connection between the application UI and business logic. When it works, it’s a wonderful thing. You no longer have to write code that updates your UI or pass values down to your business logic. When it breaks, it can be frustrating to figure out what went wrong. In this post, I will give you some tips on how you can debug your data bindings in WPF.

1. Add Tracing to the Output Window

Here is a sample TextBlock that has a missing data context. In this situation, you will not get any errors in the Visual Studio output window.

    
        
    

To enable tracing, I added a new xml namespace to include the System.Diagnostics namespace. You can also set the level of tracing to High, Medium, Low, or None. Now let’s add some tracing to the output window to see what is wrong with the data binding.

    
        
    

Now the output window will contain the following helpful information:

System.Windows.Data Warning: 71 : BindingExpression (hash=38600745): DataContext is null

2. Attach a Value Converter to Break into the Debugger

When you don’t see anything displayed in your UI, it is hard to tell whether it’s data binding causing your issue or a problem with the visual layout of the control. You can eliminate the data binding as the problem by adding a value converter and break into the debugger.  If the value is what you expected, then data binding is not your issue.

Here is a simple value converter that breaks into the debugger.

using System;
using System.Diagnostics;
using System.Globalization;
using System.Windows.Data;

namespace WpfApplication1
{
    public class DebugDataBindingConverter : 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 value converter, reference the namespace of the assembly that contains the converter and add an instance of it to the resources of your window. Now add the converter to your problematic data binding.

    
        
            
        
        
    

3. Know the Instant You Have a Data Binding Problem

Unless you are constantly checking every UI element and monitoring the output window for binding errors, you will not always catch that you have a data binding problem. An exception is not thrown when data binding breaks, so global exception handlers are of no use.

Wouldn’t it be nice if you break into the debugger the instant you have a data binding error? By adding our own implementation of a TraceListener that breaks into the debugger, we will get notified the next time we get a data binding error. I also added the default ConsoleTraceListener alongside our new DebugTraceListener, so that our previous examples of tracing output would not be broken.

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        PresentationTraceSources.Refresh();
        PresentationTraceSources.DataBindingSource.Listeners.Add(new ConsoleTraceListener());
        PresentationTraceSources.DataBindingSource.Listeners.Add(new DebugTraceListener());
        PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Warning | SourceLevels.Error;
        base.OnStartup(e);
    }
}

public class DebugTraceListener : TraceListener
{
    public override void Write(string message)
    {
    }

    public override void WriteLine(string message)
    {
        Debugger.Break();
    }
}

With these tips, you should have a more pleasant data binding experience. Please share any additional debugging tips you may have in the comments.
 

By default, Visual Studio (v2012 onwards) is configured to automatically log any binding errors detected whilst running a WPF application.

You can see examples of such in the Debug Output window:

System.Windows.Data Error: 40 : BindingExpression path error: ‘MyUnknownProperty’ property not found on ‘object’ »Product’ (HashCode=30581329)’. BindingExpression:Path=MyUnknownProperty; DataItem=’Product’ (HashCode=30581329); target element is ‘TextBox’ (Name=»); target property is ‘Text’ (type ‘String’)

This setting can be adjusted using the Debugging, Output Window settings: 

Often, it’s useful to be notified in a more intrusive manner when a binding error has been detected…rather than silently continuing, just as WPF does.

In order to add your own handling, you need to add a class that derives from TraceListener to the PresentationTraceSources.DataBindingSource.Listeners collection.

Your TraceListener needs to implement the following abstract methods:

public override void WriteLine(string message)
public override void Write(string message)

Generally, you’ll only add implementation details to the WriteLine method.  When a binding error is detected the WPF will call your WriteLine and Write methods.

Full Source:

Listing

internal class BindingListener : TraceListener{

    public static readonly BindingListener Current = new BindingListener();
 
    private const int Uninitialised = 0;
    private const int Initialised = 1;
    private int _initialised = Uninitialised;
 
    public void Initialise()
    {
        if (Interlocked.CompareExchange(ref _initialised, Initialised, Uninitialised) == Uninitialised)
        {
            PresentationTraceSources.DataBindingSource.Listeners.Add(this);
        }
    }
 
    public override void WriteLine(string message)
    {
        throw new ApplicationException(message);
    } 
    public override void Write(string message)
    {}
}

In the above example we wrap access to the BindingListener with a static Current property. When Initialise() is called, provided it’s the first time is has been called, then the class is added to PresentationTraceSources.DataBindingSource.Listeners 


It’s probably overkill using Interlocked.CompareExchange for thread-safety as generally you’ll be calling Initialise() from the main GUI thread, as your app starts up:


public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        BindingListener.Current.Initialise();
        base.OnStartup(e);
    }
}

When you run the application (in debug mode) and there is any form of binding error, you'll see following exception dialog: 



This can be quite annoying, but at least you won't miss any binding errors.

One thing to note: your listener only gets called in Debug builds!

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!):

/// &lt;summary&gt;

/// Public method Convert(object value, Type targetType, object parameter, CultureInfo culture)

/// &lt;/summary&gt;

/// &lt;param name=&quot;value&quot;&gt;&lt;/param&gt;

/// &lt;param name=&quot;targetType&quot;&gt;&lt;/param&gt;

/// &lt;param name=&quot;parameter&quot;&gt;&lt;/param&gt;

/// &lt;param name=&quot;culture&quot;&gt;&lt;/param&gt;

/// &lt;returns&gt;&lt;/returns&gt;

public object Convert(object value, Type targetType,

object parameter, CultureInfo culture)

{

if (Debugger.IsAttached)

Debugger.Break();

else

Logger.DebugFormat(&quot;Binding value in {0} = {1}&quot;, &quot;DatabindingDebugConverter::Convert&quot;, 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

Понравилась статья? Поделить с друзьями:
  • Bfsvc error failed to set element application device status c00000bb
  • Bfsvc error failed to initialize global state status c0000001
  • Bfsvc error could not open the bcd template store status c000015c
  • Bfsvc error could not open the bcd template store status c0000022
  • Bfsvc error could not open the bcd template store status c000000f windows 10