When we've made changes to our XAML, but don't see what we are expecting to see in the UI, the first place to look for errors is in the Output window of Visual Studio. If this window is not already visible, then you can display it by selecting the Output option from the View menu or by pressing Ctrl + W and then O.
However, if you have a binding error, but don't see any reference to it in the Output window, it could be because your Visual Studio is not currently set up to output debug information to it.
You can turn this functionality on in the Visual Studio Options dialog window, by navigating to Tools | Options | Debugging | Output Window | General Output Settings.
The General Output Settings section has several options that you can turn on and off. The most important ones are All debug output and Exception Messages, but it is generally good practice to leave them all set to On. When set, binding errors will be displayed in the Output window in the following format:
System.Windows.Data Error: 40 : BindingExpression path error: 'ViewName' property not found on 'object' ''MainViewModel' (HashCode=3910657)'. BindingExpression:Path=ViewName; DataItem='MainViewModel' (HashCode=3910657); target element is 'TextBox'
(Name='NameTextBox'); target property is 'Text' (type 'String')
Let's take a closer look at this error. The plain English translation for this would be as follows:
- There is no public property named ViewName in the object of type MainViewModel with a HashCode value of 3910657
- The error was raised from a Binding.Path value that was specified as ViewName, which was set on the Text property of a TextBox instance named NameTextBox
This could be rewritten with descriptive names rather than specific details, like this:
System.Windows.Data Error: 40 : BindingExpression path error: 'PropertyOfBindingSource' property not found on 'object' ''TypeOfBindingSource' (HashCode=HashCodeOfBindingSource)'. BindingExpression:Path=UsedBindingPath; DataItem='TypeOfBindingSource' (HashCode=HashCodeOfBindingSource); target element is 'TypeOfBindingTarget' (Name='NameOfBindingTarget'); target property is
'PropertyOfBindingTarget' (type 'TypeOfBindingTargetProperty')
Now that we have our 'key' to explain what these values represent, we can see that they are really very descriptive. Not only are we provided with the name of the data bound UI control, if it is set, and the used binding path, but also the type of the data source, along with the hash code of the actual instance of that type that is being used.
These errors highlight the mistakes that have been made in the XAML files. The type of errors displayed in this window will include incorrectly labeled binding paths, such as ones using non-existent property names, or otherwise invalid binding source paths. While it won't catch every problem, there is a way to make it output additional information that could help us to track down our more elusive problems.
In order to do this, first display the Options dialog window, then navigate to Tools | Options | Debugging | Output Window | WPF Trace Settings.
Here, you can find a number of options, each with a variable level of output: Animation, Data Binding, Dependency Properties, Documents, Freezable, HWND Hosting, Markup, Name Scope, Resource Dictionaries, and Routed Events. The various levels of output and their meanings are as follows:
- Critical: Enables tracing of Critical events only
- Error: Enables tracing of Critical and Error events
- Warning: Enables tracing of Critical, Error, and Warning events
- Information: Enables tracing of Critical, Error, Warning, and Information events
- Verbose: Enables tracing of Critical, Error, Warning, Information, and Verbose events
- ActivityTracing: Enables tracing of Stop, Start, Suspend, Transfer, and Resume events
It is fairly common to permanently have the Data Binding option set to Warning or Error, with the other options set to Off. The general rule of thumb when using these options is to use the minimum level required, except when trying to find problems, because they will slow down the running of the application. It should be noted however, that this extra debug trace output will not affect Release builds at all.
If you set the Data Binding entry to an output of Verbose or All and look in the Output window when running your application, you will understand why it will negatively affect performance. Even when not displaying this debug information in the Output window, the WPF Framework will still be performing a great number of checks when there are binding errors. It is, therefore, very important to clear up all errors and warnings that are displayed, to minimize the amount of work that the Framework does when trying to resolve them.