前言

在WPF开发中,将ViewModel中对象绑定到UI上时,会出现明明已经将数据对象Binding到UI,但是UI上就是不显示等等的问题。这篇博客将介绍WPF Data Binding调试相关的内容。

场景一(Binding的属性不存在)

ViewModel:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel() { Id = , Name = "Tom", Age = };
}
} public class ViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

XAML:

<StackPanel Margin="10">
<TextBlock Text="{Binding ID}" />
<TextBlock Text="{Binding Name}" Margin="0,10" />
<TextBlock Text="{Binding Age}" />
</StackPanel>

运行结果:

UI中Binding的ID值没有显示出来。请注意加粗的代码,在UI代码中,由于拼写错误,将Id写成了ID。但是这段代码在编译时不会报错,在VS Output窗口中也不会有提示/警告信息。在程序运行时,仔细查看VS Output窗口,此时会有如下信息 (对信息进行了精简)
System.Windows.Data Error: 40 : BindingExpression path error: 'ID' property not found on 'object' ''ViewModel' (HashCode=20915929)'. BindingExpression:Path=ID; DataItem='ViewModel' (HashCode=20915929); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

这段信息告诉提示说在ViewModel对象上没有找到ID属性,此时我们再去检查一下ViewModel发现,原来是将Id错误的写成了ID。一般这种错误的提示开头为:System.Windows.Data Error:

场景二(使用System.Diagnostics来追踪)

XAML:

<Window x: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="350" Width="525">
<StackPanel>
<TextBlock Text="{Binding Title}" />
</StackPanel>
</Window>

将Title属性Binding到TextBlock的Text属性上面,XAML和C#代码中均未指定DataContext属性。编译项目并运行程序,在VS Output中没有任何提示/警告信息。此时应该如何调试呢?可以通过设置PresentationTraceSources对象的TraceLevel来强制WPF输出所有的Binding方面的信息。

更多PresentationTraceSources信息可以参考:

https://msdn.microsoft.com/en-us/library/system.diagnostics.presentationtracesources.tracelevel(v=vs.110).aspx

对XAML代码进行如下修改(注意加粗的代码行):

<Window x: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="350" Width="525">
<StackPanel>
<TextBlock Text="{Binding Title, diag:PresentationTraceSources.TraceLevel=High}" />
</StackPanel>
</Window>

编译并运行程序,在VS Output窗口中可以找到关于Binding的信息(对信息进行了精简):

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 ''

注意:在Visual Studio 2010中需要进行如下设置才能看到上面的提示信息:因为VS 2010默认将下面的设为Off。

Tools -> Options -> Debugging -> Output Window -> WPF Trace Settings -> Data Binding -> set to Warning

程序一直在尝试寻找Visual Tree上的可以Binding的Title值,最终找到一个合适的,DependencyProperty.UnsetValue。

上述方法对查找单个页面Binding很有用,当然我们也可以全局的来收集这些Binding信息。在App.xaml.cs中添加:

public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
PresentationTraceSources.Refresh();
PresentationTraceSources.DataBindingSource.Listeners.Add(new ConsoleTraceListener());
PresentationTraceSources.DataBindingSource.Listeners.Add(new DebugTraceListener());
PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Warning | SourceLevels.Error;
base.OnStartup(e);
}
} public class DebugTraceListener : TraceListener
{
public override void Write(string message)
{
// Write your log here.
} public override void WriteLine(string message)
{
// Write your log here.
}
}

场景三(使用ValueConverter来调试)

场景一和场景二中的方法解决因拼写错误或者无明确DataContext时非常有效。不过有时候真正的通过VS进行调试一下,更加直观,便捷。可以使用实现一个简单的调试使用的Converter,然后将其Binding到目标上,

public class DebugConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Debugger.Break();
return value;
} public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
Debugger.Break();
return value;
}
}

Debugger.Break()的效果和VS中F9设置断点是一样的。
XAML

<Window x: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="350" Width="525">
<Window.Resources>
<local:DebugConverter x:Key="DebugConverter" />
</Window.Resources>
<StackPanel>
<TextBlock Text="{Binding Id, Converter={StaticResource DebugConverter}}" />
</StackPanel>
</Window>

感谢您的阅读~如果您有其他关于Data Binding的调试方式,欢迎在评论区指出~

[WPF]如何调试Data Binding的更多相关文章

  1. WPF中的Data Binding调试指南

    大家平时做WPF开发,相信用Visual studio的小伙伴比较多.XAML里面曾经在某些特殊版本的Visual Studio中是可以加断点进行调试的,不过目前多数版本都不支持在XAML加断点来调试 ...

  2. WPF之数据绑定Data Binding

    一般情况下,应用程序会有三层结构:数据存储层,数据处理层(业务逻辑层),数据展示层(UI界面). WPF是“数据驱动UI”. Binding实现(通过纯C#代码) Binding分为source和ta ...

  3. WPF QuickStart系列之数据绑定(Data Binding)

    这篇博客将展示WPF DataBinding的内容. 首先看一下WPF Data Binding的概览, Binding Source可以是任意的CLR对象,或者XML文件等,Binding Targ ...

  4. .NET: WPF Data Binding

    WPF是分离UI和Logic的最佳工具,不同于Window Form的事件驱动原理,WPF采用的是数据驱动,让UI成为了Logic的附属,达到分离的效果. 本篇主要讲讲wpf的精华:data bind ...

  5. Data Binding in WPF

    http://msdn.microsoft.com/en-us/magazine/cc163299.aspx#S1   Data Binding in WPF John Papa Code downl ...

  6. WPF binding<一> Data Binding在WPF中的地位

    在代码中看到 <Image Source="{Binding ElementName=LBoxImages, Path=SelectedItem.Source}" /> ...

  7. WPF教程三:学习Data Binding把思想由事件驱动转变为数据驱动

    之前大家写代码都喜欢用事件驱动,比如说鼠标输入的click事件.初始化的内容全部放在窗体加载完毕的load事件,等等,里面包含了大量的由事件触发后的业务处理代码.导致了UI和业务逻辑高度耦合在一个地方 ...

  8. WPF中的数据绑定Data Binding使用小结

    完整的数据绑定的语法说明可以在这里查看: http://www.nbdtech.com/Free/WpfBinding.pdf MSDN资料: Data Binding: Part 1 http:// ...

  9. Data Binding和INotifyPropertyChanged是如何协调工作的?

    前言 WPF的一大基础就是Data Binding.在基于MVVM架构的基础上,只有通过实现INotifyPropertyChanged接口的ViewModel才能够用于Data Binding. 要 ...

随机推荐

  1. Kibana5 数据探索使用(Discover功能)

    认识Kibana Kibana 是一个为 Logstash 和 ElasticSearch 提供的日志分析的 Web 接口.可使用它对日志进行高效的搜索.可视化.分析等各种操作.Kibana的使用场景 ...

  2. 【linux相识相知】磁盘分区及文件系统管理详解

    磁盘,提供持久的数据存储,它不像我们的内存,如果突然断电了,在内存中的数据一般都会被丢掉了,内存中的数据在保存的时候,会被写到硬盘里面,磁盘也是一种I/O设备. 我们都知道磁盘分区完成之后,还要进行格 ...

  3. opnet的simple_source模块学习 分类: opnet 2014-05-18 09:50 170人阅读 评论(0) 收藏

    simple_source模块可以在外部设置的属性 有四个局部统计量,分别为产生的bit速率.包速率.包大小,包间隔 状态机为三个非强制对象,在头文件里定义了自中断和转移条件. /*Include f ...

  4. 三.GC相关之三分钟认识GC算法

    GC算法慢慢演化,进化到了现在的分代GC.其进化过程 标记-清除算法 –> 标记-复制算法 –> 标记-整理算法 –> 分代算法. 在介绍算法之前,我们知道Java是动态加载.其特点 ...

  5. 29. leetcode 167. Two Sum II - Input array is sorted

    167. Two Sum II - Input array is sorted Given an array of integers that is already sorted in ascendi ...

  6. grunt+bower依赖管理

    安装bower(必须安装git) npm install bower -g bower按照插件命令 初始化配置 bower init 生成bower.json //如果有bower.json 直接输入 ...

  7. Python爬虫从入门到放弃(二十二)之 爬虫与反爬虫大战

    爬虫与发爬虫的厮杀,一方为了拿到数据,一方为了防止爬虫拿到数据,谁是最后的赢家? 重新理解爬虫中的一些概念 爬虫:自动获取网站数据的程序反爬虫:使用技术手段防止爬虫程序爬取数据误伤:反爬虫技术将普通用 ...

  8. 模拟生产搭建Standby RAC实验环境(11.2.0.4 DG)

    模拟生产搭建Standby RAC实验环境(11.2.0.4 DG) 环境:RHEL 6.5 + Oracle 11.2.0.4 GI.DB 1.需求背景介绍 2.准备工作 3.主库配置 4.备库配置 ...

  9. BPM与OA的区别及联系

    BPM与OA的区别及联系 近年来,在企业管理信息系统一些名词反复被提及,然而外行人对于这些名词则是一头雾水,网上的解释又鱼龙混杂,没有绝对权威的文献可供参考,因此也就让我们对这些名词的认识越来越模糊. ...

  10. .NET Core 2.0 正式发布信息汇总

    万众瞩目的.NET Core 2.0终于发布了,原定于9.19的dotnetconf大会的发布时间大大提前了1个月,.NET Core 2.0/.NET Standard 2.0的正式发布是.NET ...