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"  VerticalMoognment = "Top" HorizontalMoognment = "Right" Width = "120" /> <TextBox Height = "23" Margin = "0,99,169,0" Name = "textBox2"  VerticalMoognment = "Top" HorizontalMoognment = "Right" Width = "120" /> <TextBox HorizontalMoognment = "Right" Margin = "0,153,169,0"  Name = "textBox3" Width = "120" Height = "23" VerticalMoognment = "Top" /> <Label Height = "28" Margin = "117,42,0,0" Name = "label1"  VerticalMoognment = "Top" HorizontalMoognment = "Left" Width = "120">Item 1</Label> <Label Height = "28" HorizontalMoognment = "Left"  Margin = "117,99,0,0" Name = "label2" VerticalMoognment = "Top" Width = "120">Item 2</Label> <Label HorizontalMoognment = "Left" Margin = "117,153,0,181"  Name = "label3" Width = "120">Item 3</Label><Button Height = "23" HorizontalMoognment = "Right" Margin = "0,0,214,127"Name = "button1" VerticalMoognment = "Bottom" Width = "75"  Click = "button1_Click">Total</Button> <Label Height = "28" HorizontalMoognment = "Right"  Margin = "0,0,169,66" Name = "label4" VerticalMoognment = "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 > 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.");} } } 
}

当你编译并执行上面的代码时,它会产生如下的窗口。现在在文本框中输入值,然后按总计按钮。在对文本框中输入的所有值求和后,您将获得总值。
调试
如果您尝试输入非真实值的值,则上述应用程序将崩溃。要查找并解决问题(为什么会崩溃),您可以在按钮单击事件中插入断点。
让我们在第 1 项中写上“abc”,如下所示。
项目 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>

两个文本块的文本属性被静态设置为“姓名”和“职务”,而其他两个文本块的文本属性绑定到“名字”和“职务”,但类变量是 Employee 类中的名称和职务,如下所示。
我们故意写了一个不正确的变量名,以便了解在未显示所需输出时在哪里可以找到这种类型的错误。

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 = "Moo 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 对象的 Title,但名称未绑定。
XAML 中的调试
要检查名称发生了什么,让我们查看生成大量日志的输出窗口。
很容易找到错误只是搜索错误,你会发现以下错误,上面写着“BindingExpression path error: ‘FirstName’ property not found on ‘object’ ''Employe”

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"VerticalMoognment = "Top" Text  ="{Binding ElementName = comboBox, Path = SelectedItem.Content, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> </TextBox> </StackPanel> </Window> 

当您执行应用程序时,它将显示实时可视树,其中所有元素都显示在树中。
实时视觉树
此 Live Visual Tree 显示了完整的布局结构,以了解 UI 元素的位置。但此选项仅在 Visual Studio 2015 中可用。如果您使用的是 Visual Studio 的较旧选项,则无法使用此工具,但是还有另一个可以与 Visual Studio 集成的工具,例如 XAML Spy for Visual Studio .

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/18480.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javaIO流知识点概况

一、前言&#xff1a; 1.1.流的概念: java将输入与输出比喻为"流"&#xff0c;英文:Stream. 就像生活中的"电流","水流"一样,它是以同一个方向顺序移动的过程.只不过这里流动的是字节(2进制数据).所以在IO中有输入流和输出流之分,我们理解他们…

Vue3中使用 filter 方法通过 id 删除数组中的指定对象

Vue中使用 filter 方法通过 id 删除数组中的指定对象 一、前言1、示例2、案例 一、前言 在 Vue3 中&#xff0c;我们经常需要处理数据并进行相应操作&#xff0c;比如删除数组中的特定对象。在这篇文章中&#xff0c;我们将学习如何使用 filter 方法和响应式变量来实现这一目标…

单点11.2.0.3备份恢复到单点11.2.0.4

保命法则&#xff1a;先备份再操作&#xff0c;磁盘空间紧张无法备份就让满足&#xff0c;给自己留退路。 场景说明&#xff1a; 1.本文档的环境为同平台、不同版本&#xff08;操作系统版本可以不同&#xff0c;数据库小版本不同&#xff09;&#xff0c;源机器和目标机器部…

swiftui基础组件Image加载图片,以及记载gif动图示例

想要在swiftui中展示图片&#xff0c;可以使用Image这个组件&#xff0c;这个组件可以加载本地图片和网络图片&#xff0c;也可以调整图片大小等设置。先大概看一下Image的方法有哪些可以用。 常用的Image属性 1.调整图像尺寸&#xff1a; 使用 resizable() 方法使图像可调整…

Java如何分块读取大文件

在Java中&#xff0c;分块读取大文件通常使用FileInputStream或BufferedInputStream结合循环来实现。以下是一个基本的示例&#xff0c;展示如何分块读取大文件&#xff1a; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException…

黑龙江等保测评:强化网络安全的北方防线

在数字化时代&#xff0c;网络空间已成为国家发展的新领域&#xff0c;其安全直接关系到国家安全、社会稳定和个人隐私。作为中国东北的重要省份&#xff0c;黑龙江省积极响应国家网络安全战略&#xff0c;深入实施信息安全等级保护制度&#xff08;简称“等保”&#xff09;&a…

量子密钥分发系统基础器件(一):光纤干涉仪

干涉仪的基本原理是利用波的叠加来获得波的相位信息&#xff0c;从而获取实验中所关心的物理量。光纤干涉仪是由光学干涉仪发展而来的&#xff0c;利用光纤实现光的干涉&#xff0c;由于光纤取代透镜系统构成的光路具有柔软、形状可随意变化、传输距离远等特点&#xff0c;当前…

【Linux】23. 线程封装

如何理解C11中的多线程(了解) #include <iostream> #include <unistd.h> #include <thread>void thread_run() {while (true){std::cout << "我是新线程..." << std::endl;sleep(1);} } int main() {// 任何语言需要在Linux上实现多线…

项目结构与模块划分策略

项目结构与模块划分策略可以根据项目的规模、功能需求和团队组成进行合理的设计。以下是一些常见的策略&#xff1a; 按功能划分&#xff1a;将项目按照不同的功能划分为不同的模块。每个模块负责处理特定的功能&#xff0c;如用户管理、订单处理、支付等。这种划分方式使得代码…

Vue组件通讯$refs获取组件实例例子

在Vue中&#xff0c;$refs 是一个对象&#xff0c;它持有注册过 ref 特性 (attribute) 的所有 DOM 元素和子组件实例。你可以使用 $refs 在父组件中直接访问子组件的实例或者 DOM 元素。 下面是一个使用 $refs 获取子组件实例的例子&#xff1a; 首先&#xff0c;我们有一个子…

解决IDEA菜单栏找不到VCS的问题,且使用IDEA推送新项目到托管仓库

问题描述&#xff1a; 在idea软件中使用git推送项目&#xff0c;idea页面顶部菜单栏无VCS 解决方案&#xff1a; 一&#xff1a;File->Settings->Version Control-> 点击 ->选择项目->VCS:->点击ok&#xff1a; 二&#xff1a;托管平台创建一个Git仓库来保…

Mysql 8.0 主从复制及读写分离搭建记录

前言 搭建参考&#xff1a;搭建Mysql主从复制 为什么要做主从复制&#xff1f; 做数据的热备&#xff0c;作为后备数据库&#xff0c;主数据库服务器故障后&#xff0c;可切换到从数据库继续工作&#xff0c;避免数据丢失。架构的扩展。业务量越来越大&#xff0c;I/O访问频…

MySQL忘记密码怎么办?教你无密码登录

MySQL免密钥登录 文章目录 MySQL免密钥登录一、修改配置文件二、无密码登录三、修改root密码四、使用新密码登录 一、修改配置文件 # 这个配置项的意思是告诉mysql跳过权限验证&#xff0c;允许任何用户以任何密码登录 [rootmysql ~]# echo "skip-grant-tables" >…

6月来得及!考研数学120分复习规划:660/880/1000/1800怎么刷?

首先&#xff0c;120分是个什么概念&#xff1f; 如果目标120&#xff0c;历年真题就要135以上。这是因为&#xff1a; 1. 习题册里都是历年真题改编&#xff0c;很多题型见过了&#xff1b; 2. 考场发挥有不确定因素&#xff0c;所以需要安全边界。 总体规划 那么&#xff…

java.lang.StackOverflowError解决方案

java.lang.StackOverflowError解决方案 java.lang.StackOverflowError 是一种运行时错误&#xff0c;通常发生在递归方法调用过深&#xff0c;导致线程的调用栈溢出时。这种错误表明程序中的递归调用没有适当地结束&#xff0c;或者递归深度超过了JVM的栈大小限制。 以下是一…

FFmpeg 中 protocols 使用文档介绍

描述 FFmpeg 中用ibavformat 库来提供的输入和输出协议。 protocols选项 关于 libavformat 库中协议选项的详细信息总结: 全局选项:libavformat 库提供了一些适用于所有协议的通用全局选项。 私有选项:每个协议也可能支持特定的私有选项,这些选项仅适用于相应的组件。 设…

2105. 给植物浇水 II

2105. 给植物浇水 II 题目链接&#xff1a;2105. 给植物浇水 II 代码如下&#xff1a; //双指针法 class Solution { public:int minimumRefill(vector<int>& plants, int capacityA, int capacityB) {int res0;int i0,jplants.size()-1;int acapacityA,bcapacity…

[java基础揉碎]文件IO流

目录 文件 什么是文件 文件流​编辑 常用的文件操作 创建文件方式一 创建文件方式二 创建文件方式三 tip:为什么new file 了还有执行createNewFile?new File的时候其实是在内存中创建了文件对象, 还没有在磁盘中, 当执行createNewFile的时候才是往磁盘中写入​编辑 …

WWW24因果论文(1/8) | 利用强化学习(智能体)进行因果问答

【摘要】因果问题询问不同事件或现象之间的因果关系。它们对于各种用例都很重要&#xff0c;包括虚拟助手和搜索引擎。然而&#xff0c;许多当前的因果问答方法无法为其答案提供解释或证据。因此&#xff0c;在本文中&#xff0c;我们旨在使用因果关系图来回答因果问题&#xf…

JS-05拷贝继承

目录 1 前置问题 2 拷贝继承实现 3 拷贝封装 4 浅拷贝和深拷贝 5 应用广泛 场景&#xff1a;想使用某个对象中的属性&#xff0c;但是又不能直接修改它&#xff0c;于是就可以创建一个该对象的拷贝 1 前置问题 直接将一个对象source赋值给另一个对象target&#xff0c;此…