WPF中的Data Binding調試指南

點擊藍字“大白技術控”關注我喲

加個“星標”,每日良時,好文必達!

WPF中的Data Binding如何Debug?

大家平時做WPF開發,相信用Visual studio的小夥伴比較多。XAML代碼曾經在某些特殊版本的Visual Studio中是可以加斷點進行調試的,不過目前多數版本都不支持在XAML加斷點來調試。

那如果自己需要綁定的 Property 沒生效,該怎麼去檢測或Debug排查問題呢?下面大白給出幾種自己用過的方法,本人的開發環境是 Win10專業版x64 + Visual Studio 2019專業版v16.2.2,以下內容中給出了詳細步驟的方法都親測有效。

方法1: 修改註冊表 + 修改config文件

在註冊表中增加一個選項,

具體做法是,在目錄HKEY_CURRENT_USER\Software\Microsoft中創建文件夾Tracing, 然後在其裏面創建子文件夾WPF,然後新建一個DWORD(32位)值ManagedTracing,將其值設置爲1.

註冊表

也可以將下面的文件另存爲 trace.reg,然後雙擊進行設置。

Windows Registry Editor Version 5.00


[HKEY_CURRENT_USER\Software\Microsoft\Tracing\WPF]
"ManagedTracing"=dword:00000001

接下來,需要在你的Project的能影響 .exe.config生成的那個 .config文件下加入摺疊區域的內容:

App.config

由於我這邊相關的config文件就是App.config,所以只需在App.config中加入該內容。

圖中摺疊的部分如下:

  <system.diagnostics>
    <sources>
      <source name="System.Windows.Data" switchName="BindingSwitch" >
        <listeners>
          <add name="BindingTextListener" />
        </listeners>   
      </source>
      
       <!--<source name="System.Windows.Data" switchName="BindingSwitch" >
        <listeners>
          <add name="BindingXmlListener" />
        </listeners>      
      </source>-->


      <source name="System.Windows.DependencyProperty" switchName="BindingSwitch" >
        <listeners>
          <add name="BindingTextListener" />
        </listeners>
      </source>


      <source name="System.Windows.Freezable" switchName="BindingSwitch" >
        <listeners>
          <add name="BindingTextListener" />
        </listeners>
      </source>


      <source name="System.Windows.RoutedEvent" switchName="BindingSwitch" >
        <listeners>
          <add name="BindingTextListener" />
        </listeners>
      </source>


      <source name="System.Windows.Media.Animation" switchName="BindingSwitch" >
        <listeners>
          <add name="BindingTextListener" />
        </listeners>
      </source>


      <source name="System.Windows.NameScope" switchName="BindingSwitch" >
        <listeners>
          <add name="BindingTextListener" />
        </listeners>
      </source>


      <source name="System.Windows.ResourceDictionary" switchName="BindingSwitch" >
        <listeners>
          <add name="BindingTextListener" />
        </listeners>
      </source>


      <source name="System.Windows.Markup" switchName="BindingSwitch" >
        <listeners>
          <add name="BindingTextListener" />
        </listeners>
      </source>


      <source name="System.Windows.Documents" switchName="BindingSwitch" >
        <listeners>
          <add name="BindingTextListener" />
        </listeners>
      </source>
      
    </sources>
      
    <switches>
      <add name="BindingSwitch" value="All" />
      <!--add name="BindingSwitch" value="Off" -->
      <!--add name="BindingSwitch" value="Verbose" -->
      <!--add name="BindingSwitch" value="Warning" -->
      <!--add name="BindingSwitch" value="Activity" -->
    </switches>
    <sharedListeners>
      <!-- This listener sends output to a file named BindingTrace.log (text) -->
      <add name="BindingTextListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="BindingTrace.log" />


      <!-- 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 BindingTrace.xml -->
      <add name="BindingXmlListener" type="System.Diagnostics.XmlWriterTraceListener" traceOutputOptions="None" initializeData="BindingTrace.xml" />
    </sharedListeners>


    <trace autoflush="true" indentsize="4"></trace>
  </system.diagnostics>

設置好後,你build這個wpf項目後,當啓動Debug時,在其相應的debug目錄下會多出一個 BindingTrace.log文件,比如, 我這邊的內容上這樣的:

WPF binding - 日誌文件

我配置監聽器(listener)時,將debug的信息設置成了.log格式,與.txt格式相比其優勢是: 當用vs code打開時,自帶高亮,看起來比較爽。

      <!-- This listener sends output to a file named BindingTrace.log (text) -->
      <add name="BindingTextListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="BindingTrace.log" />

當然也有小夥伴希望將Trace信息導出爲xml,也可以的,只需將加入內容開頭部分的:

  <source>
  <listeners>
      <add name="BindingTextListener" />
    </listeners>   
  </source>
  
   <!--<source name="System.Windows.Data" switchName="BindingSwitch" >
    <listeners>
      <add name="BindingXmlListener" />
    </listeners>
      </source>  -->

改爲:

  <!-- <source>
  <listeners>
      <add name="BindingTextListener" />
    </listeners>   
  </source> -->
  
   <source name="System.Windows.Data" switchName="BindingSwitch" >
    <listeners>
      <add name="BindingXmlListener" />
    </listeners>
   </source>

即可。

那麼,此時在其相應的debug目錄下會多出一個 BindingTrace.xml文件,我這邊的內容上這樣的:

BindingTrace.xml

參考:

https://systemscenter.ru/scsm_authoringtool.en/html/b24efd85-0ced-48ea-8ecc-d816c789bae2.htm

https://www.cnblogs.com/furenjun/archive/2011/08/01/2123983.html

WPF Tutorial | Debug DataBinding Issues

https://www.wpftutorial.net/DebugDataBinding.html

45-DebuggingDataBinding · bstollnitz/old-wpf-blog

https://github.com/bstollnitz/old-wpf-blog/tree/master/45-DebuggingDataBinding

方法2: 在XAML中設置TraceLevel + 在xaml中需要debug的View對應的 .xaml.cs文件中啓用WPF Trace

該方法適用於 .NET framework 3.5以後(包括 .NET core)的WPF project.

首先需要給該View的xaml文件的某個節點加入PresentationTraceSources.TraceLevel="High",

<UserControl x:Class="CaliburnMicro_Calculator.Views.CalculatorView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:CaliburnMicro_Calculator.Views"
             xmlns:cal="http://www.caliburnproject.org"
             mc:Ignorable="d"
             Width="240">

我這邊直接在這個view的根節點<UserControl>中加入PresentationTraceSources.TraceLevel="High",結果如下:

<UserControl x:Class="CaliburnMicro_Calculator.Views.CalculatorView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:CaliburnMicro_Calculator.Views"
             xmlns:cal="http://www.caliburnproject.org"
             mc:Ignorable="d"
             Width="240" PresentationTraceSources.TraceLevel="High">

此時,我們還需要在目標View的對應的 .xaml.cs文件中啓用WPF Trace.

            // Enable WPF tracing
            PresentationTraceSources.Refresh();
            PresentationTraceSources.DataBindingSource.Listeners.Add(new ConsoleTraceListener());
            PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.All;

此時,在Output(輸出窗口)就可以看到數據綁定的相關信息了。

Output窗口

可能有人會好奇output中的紅色字體是怎麼來的,vs的output默認是黑色。

其實安裝一個vs插件VSColorOutput就好了,傳送門:

https://marketplace.visualstudio.com/items?itemName=MikeWard-AnnArbor.VSColorOutput .

當然,你還可以在此時啓用"診斷工具",位置是:調試 -> 窗口 -> 顯示診斷工具,配合起來用起來更爽喔~

VS中顯示診斷工具

方法3: Visual Studio 2019 (16.4之後的版本)安裝 XAML binding extension

這個VS插件由微軟XAML團隊推出,看起來像是實現了方法1或方法2的自動化。

XAML binding extension for Visual Studio 2019 下載地址:

https://marketplace.visualstudio.com/items?itemName=PeterSpa.XamlBinding

相關代碼已開源:

spadapet/xaml-binding-tool: XAML binding error window in a Visual Studio 2019 extension

https://github.com/spadapet/xaml-binding-tool

當安裝好這個插件時,重啓VS就可以用了,debug時,調試窗口中會多一個選項"XAML binding failures (experimental)"。點擊該選項,debug相關窗口中會顯示Data binding的詳細信息。

XAML binding failures (experimental)

此時,WPF trace level附近的...還可以點擊進行設置。

XAML binding插件 設置

方法4: 使用第三方debug工具

首推Snoop,這個工具大概2006年就出來了,歷史悠久,最初由微軟Blend團隊的Pete Blois開發,功能也異常強大,而且目前也一直有Cory Plotts 等人負責維護和更新。

Snoop主界面

左上角支持filter,屬性或層級很多時,可以快速定位目標節點。

Snoop中的Tree, Properties, Data Context均支持filter(過濾搜索),而Properties和Data Context都可以打斷點。

當某個屬性的值改變時,整個屬性的背景更改爲黃色高亮一秒鐘,以吸引用戶注意。

Snoop允許你查看您在應用程序中指定的事件列表。當你單擊元素時,你可以看到哪些元素受到影響,並查看哪個(方法或任何人)處理了該點擊。Hanlded的事件以綠色顯示。這是Snoop提供的查看隧道和事件冒泡傳遞之間的區別的強有力方法,特別是當這些事件處理得太快或根本不處理,它們如何影響您的可視化元素。

當出現binding error時,可以選擇應用程序右側的屬性,然後右鍵單擊以深入瞭解綁定或綁定表達式,以便給出更詳細的錯誤說明。

在Snoop的左上角,有一個下拉框可以打開,然後選擇"Show only Visuals with binding Errors"以查看應用程序所具有的可視數據綁定錯誤列表。

設置"Show only Visuals with binding Errors"

Snoop 的一個衆所周知的功能是能夠識別數據綁定問題。當看到組件是否綁定正確時,我通常只是嘗試一下,看看它是否有效。如果無效,我轉向 Visual Studio 調試模式下的output窗口。如果無法立即看到該值,我會這樣做:將 Snoop 附加(Attach)到我的應用,並從應用程序樹視圖上方的搜索/篩選器欄中選擇"Show only visuals with binding errors"選項。

Attach和Debug的步驟如下:

  • 以管理員權限啓動snoop

  • 在代碼裏面的合適地方加上斷點

  • Ctrl + F5 運行項目

  • 重現需要debug的界面

  • 調試 -> Debug -> 附加到進程(Attach)

然後在snoop上依次點:

Refresh按鈕, Snoop按鈕(望遠鏡),藉助filter找需要inspect的目標元素,接下來 debug就比較順暢了。

還可以使用它來顯示任何具有綁定錯誤(Binding error)的控件(就像word中的拼寫檢查一樣):

Snoop 中的綁定錯誤會紅色高亮顯示

也有小夥伴在用或WPF Inspector,不過這個工具好久沒更新了。

WPF Inspector 這個項目之前是在CodePlex上的,後來沒人維護了,目前有人手動fork到github上,但沒見任何更新。

還有小夥伴用  Mole這個Visual Studio 插件,對於這個插件,Snoop的維護者Cory Plotts等人也有參與喔,有興趣的朋友可以去試試~

Mole for Visual Studio插件下載:

Mole for VS 2015 is installed from the Visual Studio Marketplace

https://visualstudiogallery.msdn.microsoft.com/1d05cb44-8686-496b-9af3-4ed3deed3596.

Mole for VS 2017 is installed from the Visual Studio Marketplace

https://marketplace.visualstudio.com/items?itemName=KarlShifflettkdawg.MoleforVisualStudio2017.

Mole for VS 2019 is installed from the Visual Studio Marketplace

https://marketplace.visualstudio.com/items?itemName=KarlShifflettkdawg.MoleforVisualStudio2019.

mole

其他方法:

  • Binding改爲x:Binding後進行調試

  • 增加一個 ValueConverter,調用它進行調試

這兩種方法本人不太熟悉,有興趣的可以自己找相關資料去試試哈~ 有問題歡迎留言交流~

End

歡迎各位讀者加入 .NET技術交流羣,在公衆號後臺回覆“加羣”或者“學習”即可。


文末彩蛋

微信後臺回覆“asp”,給你:一份全網最強的ASP.NET學習路線圖

回覆“cs”,給你:一整套 C# 和 WPF 學習資源!

回覆“core”,給你:2019年dotConf大會上發佈的.NET core 3.0學習視頻!

回覆“so”,給你:一套給力的 超級搜索力視頻 課程!

轉發至朋友圈,是對我最大的支持。

在看+分享,人間真情 

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