WPF - 调试

这是一种识别和修复一段代码中的错误或缺陷的系统机制,这些代码与您期望的行为不同.调试子系统紧密耦合的复杂应用程序并不容易,因为修复一个子系统中的错误可能会在另一个子系统中产生错误.

在C#中调试

在WPF应用程序中,程序员处理两种语言,如C#和XAML.如果您熟悉使用任何过程语言(如C#或C/C ++)进行调试,并且您也知道断点的用法,那么您可以轻松地调试应用程序的C#部分.

我们举一个简单的例子来演示如何调试C#代码.创建一个名为 WPFDebuggingDemo 的新WPF项目.从工具箱中拖动四个标签,三个文本框和一个按钮.看一下下面的XAML代码.

<Window x:Class = "WPFDebuggingDemo.Window1" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "Window1" Height = "400" Width = "604"> 
	
   <Grid> 
      <TextBox Height = "23" Margin = "0,44,169,0" Name = "textBox1"  
         VerticalAlignment = "Top" HorizontalAlignment = "Right" Width = "120" /> 
			
      <TextBox Height = "23" Margin = "0,99,169,0" Name = "textBox2"  
         VerticalAlignment = "Top" HorizontalAlignment = "Right" Width = "120" /> 
			
      <TextBox HorizontalAlignment = "Right" Margin = "0,153,169,0"  
         Name = "textBox3" Width = "120" Height = "23" VerticalAlignment = "Top" /> 
			
      <Label Height = "28" Margin = "117,42,0,0" Name = "label1"  
         VerticalAlignment = "Top" HorizontalAlignment = "Left" Width = "120">
         Item 1</Label> 
			
      <Label Height = "28" HorizontalAlignment = "Left"  
         Margin = "117,99,0,0" Name = "label2" VerticalAlignment = "Top" Width = "120">
         Item 2</Label> 
			
      <Label HorizontalAlignment = "Left" Margin = "117,153,0,181"  
         Name = "label3" Width = "120">Item 3</Label>
			
      <Button Height = "23" HorizontalAlignment = "Right" Margin = "0,0,214,127"
         Name = "button1" VerticalAlignment = "Bottom" Width = "75"  
         Click = "button1_Click">Total</Button> 
			
      <Label Height = "28" HorizontalAlignment = "Right"  
         Margin = "0,0,169,66" Name = "label4" VerticalAlignment = "Bottom" Width = "120"/> 
			
   </Grid> 
	
</Window>

下面给出了实现按钮点击事件的C#代码.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text;
 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes;  

namespace WPFDebuggingDemo { 
   /// <summary> 
      /// Interaction logic for Window1.xaml 
   /// </summary> 
	
   public partial class Window1 : Window { 
	
      public Window1() {
         InitializeComponent();
      }
		
      private void button1_Click(object sender, RoutedEventArgs e) {
		
         if (textBox1.Text.Length > 0 && textBox2.Text.Length &gt 0 && textBox2.Text.Length > 0) {
            double total = Convert.ToDouble(textBox1.Text) + 
            Convert.ToDouble(textBox2.Text) + Convert.ToDouble(textBox3.Text); 
            label4.Content = total.ToString(); 
         } 
         else { 
            MessageBox.Show("Enter the value in all field.");
         } 
      } 
   }
}

当你编译并执行上面的代码时,它会产生以下窗口.现在在文本框中输入值,然后按"总计"按钮.总和在文本框中输入的所有值之后,您将获得总值.

Debugging

如果您尝试输入除实际值以外的值,则上述应用程序将崩溃.要查找并解决问题(为什么会崩溃),您可以在按钮单击事件中插入断点.

让我们在第1项中写下"abc",如下所示.

Item 1

单击Total按钮后,您将看到程序停止在断点处.

程序崩溃

现在移动光标对于textbox1.Text,您将看到该程序正在尝试使用其他值添加 abc 值,这就是程序崩溃的原因.

调试XAML

如果您期望在XAML中进行相同类型的调试,那么您将会惊讶地发现无法调试XAML代码,例如调试任何其他过程语言代码.当您在XAML代码中听到调试一词时,就意味着尝试找到错误.

  • 在数据绑定中,您的数据没有出现在屏幕上,你不知道为什么

  • 或者问题与复杂的布局有关.

  • 或对齐问题或边距颜色,叠加等问题,以及一些广泛的模板,如ListBox和组合框.

调试XAML程序通常用于检查绑定是否有效;如果它不起作用,那么检查什么是错的.不幸的是,除了Silverlight之外,在XAML绑定中设置断点是不可能的,但是我们可以使用"输出"窗口来检查数据绑定错误.让我们看一下下面的XAML代码,找出数据绑定中的错误.

<Window x:Class = "DataBindingOneWay.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <StackPanel Name = "Display"> 
         <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0"> 
            <TextBlock Text = "Name: " Margin = "10" Width = "100"/> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding FirstName}"/> 
         </StackPanel> 
			
         <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0"> 
            <TextBlock Text = "Title: " Margin = "10" Width = "100"/> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding Title}" /> 
         </StackPanel> 
			
      </StackPanel> 
   </Grid> 
	
</Window>

两个文本块的文本属性静态设置为"Name"和"Title",而其他两个文本块Text属性绑定到"FirstName"和"标题"但类变量是Employee类中的Name和Title,如下所示.

我们故意写了一个不正确的变量名,以便了解我们在哪里可以找到这种类型的错误当没有显示所需的输出时.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;  

namespace DataBindingOneWay { 

   public class Employee { 
      public string Name { get; set; } 
      public string Title { get; set; }  
		
      public static Employee GetEmployee() { 
		
         var emp = new Employee() { 
            Name = "Ali Ahmed", Title = "Developer" 
         }; 
			
         return emp; 
      }  
   } 
}

以下是C#代码中MainWindow类的实现.

using System; 
using System.Windows; 
using System.Windows.Controls; 
 
namespace DataBindingOneWay { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
         DataContext = Employee.GetEmployee(); 
      } 
   }
}

让我们运行这个应用程序,您可以立即在我们的MainWindow中看到我们已成功绑定到该Employee对象的标题,但名称未绑定.

在XAML中调试

要检查名称发生了什么,让我们看看生成大量日志的输出窗口.

容易发现错误只是为了搜索错误,你会发现以下错误,上面写着"BindingExpression路径错误:在'对象'上找不到'FirstName'属性'''雇员'

System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName'
   property not found on 'object' ''Employee' (HashCode=11611730)'.
   BindingExpression:Path = FirstName; DataItem = 'Employee' (HashCode = 11611730);
   target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

这清楚地表明FirstName不是Employee类的成员,因此它有助于修复此类型您的应用程序中的问题.

当您再次将FirstName更改为Name时,您将看到所需的输出.

用于XAML的UI调试工具

使用Visual Studio 2015为XAML引入了UI调试工具,以便在运行时检查XAML代码.在这些工具的帮助下,XAML代码以运行的WPF应用程序的可视树形式呈现,并且还以树中的不同UI元素属性的形式呈现.要启用这些工具,请按照以下步骤操作.

  • 转到"工具"菜单,然后从"工具"菜单中选择"选项".

  • 它将打开以下对话框.

调试工具

  • 转到左侧调试项目下的常规选项.

  • 勾选突出显示的选项,即"为XAML启用UI调试工具",然后单击"确定"按钮.

现在运行任何XAML应用程序或使用以下XAML代码.

<Window x:Class = "XAMLTestBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <ComboBox Name = "comboBox"  Margin = "50" Width = "100"> 
         <ComboBoxItem Content = "Green" /> 
         <ComboBoxItem  Content = "Yellow" IsSelected = "True" />
         <ComboBoxItem Content = "Orange" /> 
      </ComboBox> 
		
      <TextBox  Name = "textBox" Margin = "50" Width = "100" Height = "23"
         VerticalAlignment = "Top" Text  =
         "{Binding ElementName = comboBox, Path = SelectedItem.Content, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" 
         Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> 
      </TextBox> 
		
   </StackPanel> 
	
</Window>

执行应用程序时,它将显示实时可视树,其中所有元素都显示在树中.

实时视觉树

此实时视觉树显示完整的布局结构,以了解UI元素的位置.但是此选项仅在Visual Studio 2015中可用.如果您使用较旧的Visual Studio选项,则无法使用此工具,但是还有另一个可以与Visual Studio集成的工具,例如XAML Spy for Visual Studio .您可以从 xamlspy 下载