WPF調試方式

原文: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="SourceSwitchvalue="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="trueindentsize="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="SourceSwitchvalue="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="trueindentsize="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.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章