原文:http://www.cnblogs.com/furenjun/archive/2011/08/01/2123988.html
一.Output window 輸出:
<Image Source="{Binding Path=Full}"/>
System.Windows.Data Error: 35 : BindingExpression path error: 'Full' property not found on 'object' ''FileInfo' (HashCode=26218178)'. BindingExpression:Path=Full; DataItem='FileInfo' (HashCode=26218178); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource')
Disadvantage: The output window will print so much information that it may be hard to find the error you’re looking for.
二 . 使用 WPF Tracing:
We know the .net tracing: The .Net platform provides some classes to allow you to send trace messages, not only to the debug output window, but to a file, or anyone else that wants to listen. You can send traces using the static System.Diagnostics.Trace class in .Net 1.0 and in .Net 2.0 using TraceSource objects.
Please see http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource.aspx for detail.
Instead, we focus ourselves on the WPF tracing (.Config file):
1. Get the trace sources enabled first.
增加註冊表項:To enable WPF tracing in the registry, create the key
"hkey_current_user"software"microsoft"tracing"wpf", add a "ManagedTracing" DWORD value, and set it to one.
另外,當程序從debugger中啓動時,有些wpf tracing是自動註冊的,比如data binding,這樣直接可以output window看到:
Additionally, some WPF tracing is enabled automatically when you launch your app from within the debugger. Specifically, this is the case for databinding warnings and errors.
開始寫配置文件, app.config:
<configuration>
<system.diagnostics>
<sources>
<!--
<source name="System.Windows.Data" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
-->
<!--
<source name="System.Windows.DependencyProperty" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
-->
<!--
<source name="System.Windows.Freezable" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
-->
<!--
<source name="System.Windows.RoutedEvent" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
-->
<!--
<source name="System.Windows.Media.Animation" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
-->
<!--
<source name="System.Windows.NameScope" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
-->
<!--
<source name="System.Windows.ResourceDictionary" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
-->
<!--
<source name="System.Windows.Markup" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
-->
<!--
<source name="System.Windows.Documents" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
-->
</sources>
<switches>
<add name="SourceSwitch" value="All" />
<!--add name="SourceSwitch" value="Off" -->
<!--add name="SourceSwitch" value="Verbose" -->
<!--add name="SourceSwitch" value="Warning" -->
<!--add name="SourceSwitch" value="Activity" -->
</switches>
<sharedListeners>
<!-- This listener sends output to the console -->
<add name="console"
type="System.Diagnostics.ConsoleTraceListener"
initializeData="false"/>
<!-- This listener sends output to an Xml file named AvTrace.xml -->
<add name="xmlListener"
type="System.Diagnostics.XmlWriterTraceListener"
traceOutputOptions="None"
initializeData="AvTrace.xml" />
<!-- This listener sends output to a file named AvTrace.txt -->
<add name="textListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="AvTrace.txt" />
</sharedListeners>
<trace autoflush="true" indentsize="4"></trace>
</system.diagnostics>
</configuration>
Source tag, 指出你是需要探測那個命名空間的信息(only the message generated in System.Windows.Markup namespace). Data binding 在System.windows.Data空間下。
<source name="System.Windows.Markup" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
Swithes tag, 指出需要的message檔次, 需要所有的信息則value=”All”, 還可以是off,Verbose,Warning,Activity等,詳見SourceLevel in .net reflector.
<switches>
<add name="SourceSwitch" value="All" />
<!--add name="SourceSwitch" value="Off" -->
<!--add name="SourceSwitch" value="Verbose" -->
<!--add name="SourceSwitch" value="Warning" -->
<!--add name="SourceSwitch" value="Activity" -->
</switches>
trace level, 即value
Off | Output no tracing and debugging messages. | |
Error | Output error-handling messages. | |
Warning | Output warnings and error-handling messages. | |
Info | Output informational messages, warnings, and error-handling messages. | |
Verbose | Output all debugging and tracing messages. |
sharedListeners tag, 指定輸出方式:
<sharedListeners>
<!-- This listener sends output to the console -->
<add name="console"
type="System.Diagnostics.ConsoleTraceListener"
initializeData="false"/>
<!-- This listener sends output to an Xml file named AvTrace.xml -->
<add name="xmlListener"
type="System.Diagnostics.XmlWriterTraceListener"
traceOutputOptions="None"
initializeData="AvTrace.xml" />
<!-- This listener sends output to a file named AvTrace.txt -->
<add name="textListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="AvTrace.txt" />
</sharedListeners>
<trace autoflush="true" indentsize="4"></trace>
可以輸出到console, xml, txt , 文件默認地址debug目錄下。
以上可以用程序實現:
PresentationTraceSources.Refresh() //註冊
PresentationTraceSources.RoutedEventSource.Listeners.Add(new DefaultTraceListener() )
PresentationTraceSources.RoutedEventSource.Switch.Level = SourceLevels.All
(詳見http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource.aspx)
優點:
1, 把你需要的信息從output window中分離出來
2, 能夠調試wpf其他地方的程序,而不僅僅是binding,
3, 能看到低層的信息,比如information ,warning, 這些在output window 中看不到
缺點:
1.顯示某個空間下所有的信息,比如調試binding,會把所有的binding信息顯示出來,而如果我只是想看一個binding的情況,需要尋找。
2.以上兩種方法都是在binding失敗的時候,如果成功,但是現實的東西不是自己的預期,怎麼辦?
三. .net3.5新特徵: Set trace level Attached property
引用System.Diagnostics:
<xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase">
Add attached property
<Image Source="{Binding Path=Full, diagnostics:PresentationTraceSources.TraceLevel=High}" >
能把一個binding的從創建到獲得具體值等信息全部顯示出來
Output window:
System.Windows.Data Warning: 47 : Created BindingExpression (hash=17128415) for Binding (hash=11679222)
System.Windows.Data Warning: 49 : Path: 'FullName'
System.Windows.Data Warning: 51 : BindingExpression (hash=17128415): Default mode resolved to OneWay
System.Windows.Data Warning: 52 : BindingExpression (hash=17128415): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 53 : BindingExpression (hash=17128415): Attach to System.Windows.Controls.Image.Source (hash=33986010)
System.Windows.Data Warning: 58 : BindingExpression (hash=17128415): Resolving source
System.Windows.Data Warning: 61 : BindingExpression (hash=17128415): Found data context element: Image (hash=33986010) (OK)
System.Windows.Data Warning: 69 : BindingExpression (hash=17128415): Activate with root item FileInfo (hash=54701786)
System.Windows.Data Warning: 98 : BindingExpression (hash=17128415): At level 0 - for FileInfo.FullName found accessor ReflectPropertyDescriptor(FullName)
System.Windows.Data Warning: 94 : BindingExpression (hash=17128415): Replace item at level 0 with FileInfo (hash=54701786), using accessor ReflectPropertyDescriptor(FullName)
System.Windows.Data Warning: 91 : BindingExpression (hash=17128415): GetValue at level 0 from FileInfo (hash=54701786) using ReflectPropertyDescriptor(FullName): 'C:"Documents and Settings"louya"Local Settings"Temporary Internet Files"Content.IE5"AN0U1MZ3"20081026150238d02bc[1].jpg'
System.Windows.Data Warning: 71 : BindingExpression (hash=17128415): TransferValue - got raw value 'C:"Documents and Settings"louya"Local Settings"Temporary Internet Files"Content.IE5"AN0U1MZ3"20081026150238d02bc[1].jpg'
System.Windows.Data Warning: 75 : BindingExpression (hash=17128415): TransferValue - implicit converter produced BitmapFrameDecode (hash=63141826)
System.Windows.Data Warning: 78 : BindingExpression (hash=17128415): TransferValue - using final value BitmapFrameDecode (hash=63141826)
優點:
允許在binding成功後知道更多,有利於查找邏輯錯誤
缺點:
給output window增加太多的東西
四.爲binding 增加Converter class
爲binding增加一個沒有操作的converter ,設置斷點從中看到binding的值
<Image Source="{Binding Path=FullName, Converter={StaticResource photoBindingConverter}}">
public class PhotoBindingConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Return value;
}
#endregion }
優點:容易實現; 不依賴於output window;可以看到binding成功時候的信息
缺點:不能顯示像設置trace level那麼多的信息; 如果binding失敗,可能到不了convert 方法。
五.Other Tricks
1. 用DependencyPropertyHelper.GetValueSource(DependencyObject,DependencyProperty)來查看DP的運行時信息:
ValueSource e = DependencyPropertyHelper.GetValueSource(Window1, Background);
ValueSource 是一個結構體,包括信息(MSDN):
Properties
Name | Description | |
---|---|---|
BaseValueSource | Gets a value of the BaseValueSource enumeration, which reports the source that provided the dependency property system with a value. | |
IsAnimated | Gets a value that declares whether the property is being animated. | |
IsCoerced | Gets a value that declares whether this value resulted from a CoerceValueCallbackimplementation applied to a dependency property. | |
IsExpression | Gets a value that declares whether this value resulted from an evaluated expression. This might be a BindingExpression supporting a binding, or an internal expression such as those that support the DynamicResource Markup Extension. |
BaseValueSource枚舉數據爲:
Member name | Description | |
---|---|---|
Unknown | Source is not known. This is the default value. | |
Default | Source is the default value, as defined by property metadata. | |
Inherited | Source is a value through property value inheritance. | |
DefaultStyle | Source is from a setter in the default style. The default style comes from the current theme. | |
DefaultStyleTrigger | Source is from a trigger in the default style. The default style comes from the current theme. | |
Style | Source is from a style setter of a non-theme style. | |
TemplateTrigger | Source is a trigger-based value in a template that is from a non-theme style. | |
StyleTrigger | Source is a trigger-based value of a non-theme style. | |
ImplicitStyleReference | Source is an implicit style reference (style was based on detected type or based type). This value is only returned for the Style property itself, not for properties that are set through setters or triggers of such a style. | |
ParentTemplate | Source is based on a parent template being used by an element. | |
ParentTemplateTrigger | Source is a trigger-based value from a parent template that created the element. | |
Local | Source is a locally set value. |
2. Snoop, reflector tool
3. 在使用xaml時, 我們經常會碰到XamlParseException, Visual Studio的默認這個異常處理包含信息太少,而且不能正確定位到xaml中異常所在位置。錯誤經常是這樣:
An unhandled exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Additional information: Cannot create instance of 'Window1' defined in assembly 'GalaSoftLb.Wpf.MyApplication, Version=1.0.2629.15160, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation. Error in markup file 'Window1.xaml' Line 1 Position 9.
改進方法a:因爲xaml解析是在InitializeComponent()中進行,可以參看比較詳細的信息
public partial class Window1 : System.Windows.Window
{
public Window1()
{
try
{
InitializeComponent();
}
catch ( Exception ex )
{
// Log error (including InnerExceptions!)
// Handle exception
}
}
}
改進方法b:
Open the "Exceptions" window (Debug/Exceptions) in Visual Studio.
- Click "add"
- Add "System.Windows.Markup.XamlParseException"
- Check the box to break on throw for this exception.
- Hit F5!
You'll find that the XamlParseException you catch is much more descriptive, and will give the correct position in the xaml file.
Appendix: WPF tracing namespaces
· System.Windows.Data
This is probably the most useful trace source, and provides all kinds of information about WPF databinding, including warnings when it wasn’t possible to resolve a binding. This trace source does one thing that the other WPF trace sources do not, it enables
itself automatically when you start your app in the debugger.
· System.Windows.DependencyProperty
This is probably the least useful trace source, and just provides information about registration of DPs. Unfortunately it doesn’t provide information such as property values being set and calculated.
· System.Windows.Freezable
This provides tracing about Freezable problems that don’t cause an exception. For example, if you call the CanFreeze method on a Freezable and it returns false, this tracing might be able to help you determine what exactly couldn’t be frozen.
· System.Windows.RoutedEvent
Provides tracing information on the routing of RoutedEvents, including a trace indicating what event listener handled the event.
· System.Windows.Media.Animation
Sends traces when storyboards are started, stopped, paused, resumed, etc.
· System.Windows.NameScope
Sends a trace when a name is registered, providing the name and the object.
· System.Windows.ResourceDictionary
Sends traces when a resource is set, removed, looked up, etc. Since there could be multiple resource dictionaries that define the same resource, this can be a useful way to determine where the resource is actually coming from.
· System.Windows.Markup
This sends traces when Xaml (or Baml) is loaded, with information such as the objects being created, the properties being set, and the type converters being used.
· System.Windows.Documents
Traces information about page formatting errors for paginated documents.