Objective
In WPF development, when you bind an object in ViewModel to the UI, there is an issue that clearly binds the data object to the UI, but the UI is not displayed, and so on. This blog will describe the WPF Data binding debugging related content.
Scene One (the binding attribute does not exist)
ViewModel:
Public Partial classmainwindow:window{ PublicMainWindow () {InitializeComponent (); This. DataContext =NewViewModel () {Id = -, Name ="Tom", age = -}; }} Public classviewmodel{Public int Id { get; Set ; } Public stringName {Get;Set; } Public intAge {Get;Set; }}
Xaml:
<StackPanelMargin= "Ten"> <TextBlock Text= "{Binding ID}" /> <TextBlockText="{Binding Name}"Margin= "0,10" /> <TextBlockText="{Binding Age}" /></StackPanel>
Operation Result:
The ID value of the binding in the UI is not displayed. note The bold code , which, in the UI code, writes the ID as an ID because of a misspelling. However, this code does not error at compile time , and there is no prompt/warning message in the VS Output window. When the program is running, look closely at the VS Output window, which will have the following information (streamlining the information)
System.Windows.Data Error: 40:bindingexpression path Error: ' ID ' property not found on ' object ' ViewMode L ' (hashcode=20915929) '. Bindingexpression:path=id; Dataitem= ' ViewModel ' (hashcode=20915929); Target element is ' TextBlock ' (name= '); Target property is ' Text ' (type ' String ')
This message tells the hint that the id attribute is not found on the ViewModel object, and then we go to check the ViewModel discovery, the original ID is incorrectly written ID. The general hint of this error starts with:System.Windows.Data error:
Scenario two (using System.Diagnostics to track)
Xaml:
<Windowx:class= "Wpfbindingdebug.mainwindow"xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x= "Http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d= "http://schemas.microsoft.com/expression/blend/2008"XMLNS:MC= "http://schemas.openxmlformats.org/markup-compatibility/2006"mc:ignorable= "D"Title= "MainWindow"Height= " the"Width= "525"> <StackPanel> <TextBlockText="{Binding Title}" /> </StackPanel></Window>
The title attribute is binding to the Text property of TextBlock, and neither XAML nor C # code specifies the DataContext property. Compile the project and run the program without any hint/warning information in VS output. How should you debug it at this point? You can force WPF to output all of the binding information by setting the TraceLevel of the Presentationtracesources object.
For more presentationtracesources information, refer to:
Https://msdn.microsoft.com/en-us/library/system.diagnostics.presentationtracesources.tracelevel (v=vs.110). aspx
Make the following modifications to the XAML code (note the bold lines of code):
<Windowx:class= "Wpfbindingdebug.mainwindow"xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x= "Http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d= "http://schemas.microsoft.com/expression/blend/2008"XMLNS:MC= "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:diag= "Clr-namespace:system.diagnostics;assembly=windowsbase" mc:ignorable= "D"Title= "MainWindow"Height= " the"Width= "525"> <StackPanel> <TextBlockText="{Binding Title, diag:presentationtracesources.tracelevel=high}" /> </StackPanel></Window>
Compiling and running the program, you can find information about the binding in the VS Output window (the information is streamlined):
System.Windows.Data warning:56:created bindingexpression (hash=39201736) for Binding (hash=44325851)
System.Windows.Data warning:58:path: ' Title '
System.Windows.Data warning:60:bindingexpression (hash=39201736): Default mode resolved to OneWay
System.Windows.Data warning:61:bindingexpression (hash=39201736): Default update trigger resolved to PropertyChanged
System.Windows.Data warning:62:bindingexpression (hash=39201736): Attach to System.Windows.Controls.TextBlock.Text ( hash=17911681)
System.Windows.Data warning:67:bindingexpression (hash=39201736): Resolving source
System.Windows.Data warning:70:bindingexpression (hash=39201736): Found Data context Element:textblock (hash=17911681 ) (OK)
....
System.Windows.Data warning:67:bindingexpression (hash=39201736): Resolving source
System.Windows.Data warning:70:bindingexpression (hash=39201736): Found Data context Element:textblock (hash=17911681 ) (OK)
System.Windows.Data warning:71:bindingexpression (hash=39201736): DataContext is null
System.Windows.Data warning:67:bindingexpression (hash=39201736): Resolving source (Last Chance)
System.Windows.Data warning:70:bindingexpression (hash=39201736): Found Data context Element:textblock (hash=17911681 ) (OK)
System.Windows.Data warning:78:bindingexpression (hash=39201736): Activate with root item <null>
System.Windows.Data warning:106:bindingexpression (hash=39201736): Item at level 0 is null-no accessor
System.Windows.Data warning:80:bindingexpression (hash=39201736):Transfervalue-got raw Value {Dependencyproperty.unsetvalue}
System.Windows.Data warning:88:bindingexpression (hash=39201736): transfervalue-using fallback/default value '
System.Windows.Data warning:89:bindingexpression (hash=39201736): transfervalue-using final Value '
Note : in Visual Studio , you need to set the following settings to see the above message: Because the VS 2010 defaults to the following set to OFF.
Settings, Data Binding, Output Window, Options-Debugging, Tools---Warning
The program has been trying to find a binding title value on the visual tree, eventually finding a suitable, dependencyproperty.unsetvalue.
The above method is useful for finding a single page binding, but we can also collect the binding information globally. Add in App.xaml.cs:
Public Partial classapp:application{protected Override voidOnstartup (StartupEventArgs e) {Presentationtracesources.refresh (); PRESENTATIONTRACESOURCES.DATABINDINGSOURCE.LISTENERS.ADD (NewConsoletracelistener ()); PRESENTATIONTRACESOURCES.DATABINDINGSOURCE.LISTENERS.ADD (NewDebugtracelistener ()); PresentationTraceSources.DataBindingSource.Switch.Level= Sourcelevels.warning |Sourcelevels.error; Base. Onstartup (e); }} Public classdebugtracelistener:tracelistener{ Public Override voidWrite (stringmessage) { //Write your log here. } Public Override voidWriteLine (stringmessage) { //Write your log here. }}
Scenario three (using Valueconverter to debug)
Scenario One and scenario two methods are very effective when misspelled or not explicitly datacontext. But sometimes it's more intuitive and convenient to actually debug with vs. You can use the converter that implements a simple debug, and then binds it to the target,
Public classdebugconverter:ivalueconverter{ Public ObjectConvert (ObjectValue, Type TargetType,Objectparameter, CultureInfo culture) { debugger.break (); returnvalue; } Public ObjectConvertback (ObjectValue, Type TargetType,Objectparameter, CultureInfo culture) {Debugger.break (); returnvalue; }}
The effect of Debugger.break () is the same as the F9 setting breakpoint in vs.
Xaml
<Windowx:class= "Wpfbindingdebug.mainwindow"xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x= "Http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d= "http://schemas.microsoft.com/expression/blend/2008"XMLNS:MC= "http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local= "Clr-namespace:wpfbindingdebug"mc:ignorable= "D"Title= "MainWindow"Height= " the"Width= "525"> <window.resources> <local:debugconverter x:key= "Debugconverter" /> </window.resources> <StackPanel> <TextBlock Text= "{Binding Id, Converter={staticresource Debugconverter}}" /> </StackPanel></Window>
Thank you for reading ~ If you have other debugging methods about data binding, please indicate in the comment area ~
[WPF] How to debug data Binding