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

OffOutput no tracing and debugging messages.
 ErrorOutput error-handling messages.
 WarningOutput warnings and error-handling messages.
 InfoOutput informational messages, warnings, and error-handling messages.
 VerboseOutput 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
 BaseValueSourceGets a value of the BaseValueSource enumeration, which reports the source that provided the dependency property system with a value.
 IsAnimatedGets 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.
IsExpressionGets 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
 UnknownSource is not known. This is the default value.
 DefaultSource is the default value, as defined by property metadata.
 InheritedSource is a value through property value inheritance.
 DefaultStyleSource is from a setter in the default style. The default style comes from the current theme.
 DefaultStyleTriggerSource is from a trigger in the default style. The default style comes from the current theme.
 StyleSource is from a style setter of a non-theme style.
 TemplateTriggerSource is a trigger-based value in a template that is from a non-theme style.
 StyleTriggerSource is a trigger-based value of a non-theme style.
 ImplicitStyleReferenceSource 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.
 ParentTemplateSource is based on a parent template being used by an element.
 ParentTemplateTriggerSource is a trigger-based value from a parent template that created the element.
 LocalSource 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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值