【WPF】桌面程序开发之窗口的用户控件详解

使用Visual Studio开发工具,我们可以编写在Windows系统上运行的桌面应用程序。其中,WPF(Windows Presentation Foundation)项目是一种常见的选择。然而,对于初学者来说,WPF项目中xaml页面的布局设计可能是一个难点。下面,将简要介绍WPF项目页面中使用的用户控件知识。

文章目录

  • 页面布局
    • 数据绑定
    • 数据模型
  • 用户控件
    • 创建
    • 引用
  • 控件属性
    • 自定义属性
    • 注册属性
    • 数据绑定
    • 数据监听

如果还不知道怎么创建WPF项目, 可以看以下文章,回顾一下再来

Windows系统桌面应用程序编程开发新手入门-打造自己的小工具
可以跳过…
桌面程序开发之xaml页面绑定数据模型详解

页面布局

带后缀名xaml的是页面的布局文件,打开第一个窗体布局文件,内容如下

<Window x:Class="WpfApp2.MainWindow"...xmlns:local="clr-namespace:WpfApp2"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Window.Resources><!-- 这里设置统一控件的样式 --></Window.Resources>    <Grid><TextBlock Text="{Binding key1, FallbackValue='zs1028', TargetNullValue='未初始化赋值'}" FontSize="14" Foreground="Blue"/><Button Click="Button_Click">点击按钮</Button><!-- 这里开始添加用户控件布局 --></Grid>
</Window>

注意内容中添加一个文本和一个按钮控件

当前设计器显示,如下图
在这里插入图片描述

数据绑定

在窗体的代码中修改,绑定数据,

初始化一个自定义对象来绑定的数据,代码如下

public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();// 用一个自定义对象来持有数据DataContextthis.DataContext = new DataModel();}private void Button_Click(object sender, RoutedEventArgs e){DataModel data = (DataModel)this.DataContext;data.key1 = "hello zs1028";}
}

数据模型

上面用到了一个数据模型类DataModel

需要自己单独写出来,代码如下

class DataModel : INotifyPropertyChanged
{public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}public string key1{get { return _key1; }set{_key1 = value;OnPropertyChanged(nameof(key1));}}private string _key1 { get; set; }public Data(){}
}

用户控件

在页面布局中,那些可以拼接和细分的区块,均可被视为用户控件。

用户控件具有高度的灵活性和可复用性,既可以自行创建,也可以利用已有的控件进行复用。这样的特性使得用户控件在管理和维护上变得非常便捷,同时也大大提升了使用的便利性。

前面所讲述的是对基础知识的理解和掌握,

接下来,我将详细阐述一下,如何创建用户控件,

创建

在项目目录下,新建一个文件夹Controls来存放一些用户控件,

然后在选中的文件夹名称下点鼠标右键,如下图
在这里插入图片描述

假设新建的用户控件名称为UsesrControl1,如下图
在这里插入图片描述
添加后,打开这个文件UserControl1.xaml,布局内容如下

<UserControl x:Class="WpfApp2.UserControl1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"... xmlns:local="clr-namespace:WpfApp2"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid><!-- 这里开始添加控件布局 --></Grid>
</UserControl>

在用户控件中添加一个文本控件

<TextBlock Text="{Binding key1, FallbackValue='zs1028', TargetNullValue='未初始化赋值'}" FontSize="14" Foreground="Red"/>

看文本控件绑定了一个属性key1,默认都是它所在的窗体上绑定的数据模型上的

引用

打开主窗口页面布局文件MainWindow.xaml

在按钮控件后面添加,内容如下

<local:UserControl1 />

在主页面布局中使用这个用户控件,

如果显示下划波浪线,提示它不存在,如下图
在这里插入图片描述
这需要重新编译下项目,

选中项目名,鼠标右键选择重新生成,如下图
在这里插入图片描述
它会自动处理好未添加引用问题,

当前设计器显示,如下图
在这里插入图片描述

点击运行,查看效果,

然后点击按钮,这两个文本标签就会一起更新,如下图
在这里插入图片描述

这是因为用户控件的属性绑定默认是向上寻找数据的,
找到后会自动绑定到带属性key1DataContext数据上下文对象

控件属性

用户控件是支持嵌套使用的组件。

也就是说,一个用户控件可以包含多个其他用户控件作为其组成部分。

自定义属性

为了防止在嵌套多个用户控件时发生数据绑定的混淆,我们为每个用户控件定义了独特的属性。这样,在实际使用中,就可以通过传递这些属性的值来进行参数传递,从而确保数据的清晰与准确。

可以通过窗体的绑定数据进行参数传递,或者利用父级用户控件中的数据来为其子控件传递参数。

在窗体布局中,给用户控件添加一个自定义的属性,如下图
在这里插入图片描述
这个自定义属性提示未找到属性,

需要自己定义一个属性,在用户控件中添加一个属性代码,代码如下

public string MyText { get; set; }

在用户控件布局中的添加一个新的文本控件,

就在之前的文本控件后面添加,内容如下

<TextBlock Margin="10,20" Text="{Binding MyText, FallbackValue='zs1028', TargetNullValue='未初始化赋值', RelativeSource={RelativeSource AncestorType=local:UserControl1}}" FontSize="14" Foreground="Orange"/>

其中RelativeSource,可将控件绑定到自身或其父控件上

如对象RelativeSource使用属性AncestorType为用户控件类型,它就会绑定到自身,

否则,它会自动绑定到父控件的DataContext数据上下文对象。

运行的话,如果引发异常,如下图
在这里插入图片描述

提示这个属性未注册,需要设置可以用来支持绑定Binding的属性类型

注册属性

将属性MyText代码修改,添加后,代码如下

public string MyText
{get{return GetValue(MyTextProperty) as string;}set{SetValue(MyTextProperty, value);}
}

其中MyTextProperty属性是一个自定义的静态字段,类型为DependencyProperty,支持绑定数据,

添加这个字段,代码如下

public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register("MyText", typeof(String), typeof(UserControl1));

其中传入的参数MyText就是注册的控件属性名称

运行看看效果,如下图
在这里插入图片描述

数据绑定

如果要更新那个文本控件内容,就这样做,

在窗体布局中修改一下用户控件的属性为绑定数据,内容如下

<local:UserControl1 MyText="{Binding key1}" />

再运行看看效果,如下图
在这里插入图片描述

正如预期,文本控件的内容已经同步更新了。

如果绑定失败,可点击程序窗口上悬浮的调试工具条的绑定图标按钮,如下图
在这里插入图片描述
看看为什么会绑定失败

数据监听

如果在用户控件中需要监听属性绑定的数据是否改变,

需要在属性的注册方法中添加一个监听方法,

修改用户控件的代码,代码如下

public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register("MyText", typeof(String), typeof(UserControl1), new PropertyMetadata(OnMyTextPropertyChanged));

其中OnMyTextPropertyChanged是监听属性的改变事件,
在创建的对象PropertyMetadata有个参数可以传属性的默认值

在方法OnMyTextPropertyChanged里面,实现更新的处理

private static void OnMyTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{var uc = d as UserControl1;var newValue = e.NewValue as string;var oldValue = e.OldValue as string;//...
}

其中NewValue是改变后的值,OldValue是改变前的值,都是对象,取值前需要做对应的类型转换,

处理完时可调用用户控件对象UserControl1来更新,

更多了解请参考微软官方文档的RelativeSource类别

写到这里为止,先溜了…
在这里插入图片描述

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

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

相关文章

Type-C接口桌面显示器的优势

随着科技的飞速发展&#xff0c;电子设备的连接性、便捷性和高效性成为了消费者关注的重点。在这个背景下&#xff0c;Type-C接口桌面显示器以其卓越的性能和广泛的兼容性&#xff0c;正逐步成为市场上的主流选择。本文将深入探讨Type-C接口桌面显示器的优势、应用场景、市场现…

【期刊】论文索引库-SCI\SSCI\IE\南大核心\北大核心\CSCD等

外文期刊检索 SCI SCI即《科学引文索引》(Science Citation Index),是由美国科学信息研究所(Institute for Scientific Information)创建于1961年,收录文献的作者、题目、源期刊、摘要、关键词,不仅可以从文献引证的角度评估文章的学术价值,还可以迅速方便地组建研究课…

17年数据结构考研真题解析

第一题&#xff1a; 解析&#xff1a; 我们说递归要找出口&#xff0c;这道题的出口是sum<n&#xff0c;经过观察可以得知&#xff1a;sum123。。。k 设第k次循环跳出&#xff0c;则有sum123。。。k<n k<,很显然答案选B 第二题&#xff1a; 解析&#xff1a; 第一句&a…

SPDK从安装到运行示例程序

SPDK从安装到运行示例程序 #mermaid-svg-Z8t56NOBnEyfhdpX {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Z8t56NOBnEyfhdpX .error-icon{fill:#552222;}#mermaid-svg-Z8t56NOBnEyfhdpX .error-text{fill:#552222;s…

安全、稳定、SLA高达99.9%:Azure OpenAI数据分离与隔离优势

近期有不少客户&#xff0c;由于其开发的系统软件是面向海外以及政企的&#xff0c;又想通过微软Azure OpenAI服务将大模型接入其业务作为优势&#xff0c;因此非常重视服务的安全性和稳定性。 下面将重点介绍微软Azure OpenAI 服务的数据、隐私和安全内容。 稳定&#xff1a;S…

Android OpenGLES2.0开发(一):艰难的开始

生而为人&#xff0c;本质上&#xff0c;都是孤独的&#xff01; 引言 我一直觉得OpenGL ES是一块硬骨头&#xff0c;每次用到GLSurfaceView作为Camera的预览视图时&#xff0c;总是去网上找现成的代码。CtrlC和CtrlV之后总有一种沾沾自喜的感觉&#xff0c;但是你要让我改里面…

计算机基础知识

计算机的组成部件 CPU CPU 由运算器和控制器组成&#xff0c;在下面的冯诺依曼体系中&#xff0c;我直接将控制器和运算器直接合并一起来说&#xff0c;也就是CPU&#xff0c;所以你可能在一些书籍上看到冯诺依曼体系是由五大部件构成的&#xff0c;其中CPU 就包含了两大部件…

docker 部署 Seatunnel 和 Seatunnel Web

docker 部署 Seatunnel 和 Seatunnel Web 说明&#xff1a; 部署方式前置条件&#xff0c;已经在宿主机上运行成功运行文件采用挂载宿主机目录的方式部署SeaTunnel Engine 采用的是混合模式集群 编写Dockerfile并打包镜像 Seatunnel FROM openjdk:8 WORKDIR /opt/seatunne…

提示词工程 (Prompt Engineering) 最佳实践

prompt Engineering 概念解析 提示工程是一门较新的学科&#xff0c;关注提示词开发和优化&#xff0c;帮助用户将大语言模型&#xff08;Large Language Model, LLM&#xff09;用于各场景和研究领域。研究人员可利用提示工程来提升大语言模型处理复杂任务场景的能力&#xf…

深度学习之入门书籍

自学深度学习&#xff0c;书籍很重要。 从我个人来说&#xff0c;我不太习惯英译版本&#xff0c;或者那些牛人说的&#xff0c;直接读英文&#xff0c;我是水平不够。只讲自己的经验。牛人绕道。 推荐书籍: 深度学习:从入门到精通&#xff0c;这本书不错。把基础的深度学习的…

傅里叶变换(对称美)

傅里叶变换&#xff08;对称美&#xff09; 冲浪时发现的有趣文章&#xff0c;学习自https://zhuanlan.zhihu.com/p/718139299 摘下来的内容&#xff1a; 傅里叶变换之所以“怪美的嘞”&#xff0c;根本在于它有一种内在的对称性&#xff0c;这一点在上面的图并没有表现出来…

【Golang】关于Go语言字符串转换strconv

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

【操作系统】三、内存管理:2.虚拟内存管理(虚拟内存特:局部性原理、请求分页管理方式、页面置换算法)

七、虚拟内存管理 文章目录 七、虚拟内存管理1.常规存储器特征1.1一次性1.2驻留性 2.虚拟内存特征2.1局部性原理2.2多次性2.3对换性2.4虚拟性2.5虚拟存储器的容量 3.虚拟内存的实现❗3.1缺页率3.2请求分页&#xff08;请求页表&#xff09;3.2.1页表机制❗3.2.2缺页中断机构3.2…

猝发传输和非猝发传输

猝发传输和非猝发传输是两种不同的数据传输方式&#xff0c;主要区别在于数据传输的连续性以及数据包的发送方式。 猝发传输 (Burst Transmission): 定义: 猝发传输是指在一段时间内&#xff0c;大量数据包集中发送&#xff0c;然后在一段时间内没有数据传输&#xff0c;这种…

Facebook公共主页bug问题解决措施清单

在使用Facebook的过程中&#xff0c;许多用户可能会遇到一些让人困扰的BUG&#xff0c;这些问题往往会让人感到无奈。为了帮助大家更好地应对这些情况&#xff0c;本文将总结一些常见的BUG以及对应的解决方案&#xff0c;主要集中在公共主页的相关问题。如果感兴趣就请读下去吧…

uniapp 使用Vue3 setup引入 uniapp 的onReachBottom

在page.json中加入**“onReachBottonDistance”: 50**&#xff0c;这是距离底部多少开始触发 然后再对应的页面通过import将uniapp的api引入进去 dcloudio/uni-app是不用单独下载的&#xff0c;直接用就行 import {onReachBottom,} from dcloudio/uni-app;然后直接使用就好

【ArcGIS Pro实操第三期】多模式道路网构建(Multi-model road network construction)原理及实操案例

ArcGIS Pro实操第三期&#xff1a;多模式道路网构建原理及实操案例 1 概述1.1 原理 2 GIS实操2.1 新建文件并导入数据2.2 创建网络数据集2.3 设置连接策略&#xff08;Setting up connectivity policies&#xff09;2.4 添加成本&#xff08;Adding cost attributes&#xff09…

【C++报错已解决】std::ios_base::sync_with_stdio

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

java项目之作业管理系统设计与实现源码(springboot)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的作业管理系统设计与实现源码。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 作业管理系统…

引入的pyside2后 Lib\site-packages\PySide2中没有pyside2-uic.exe

只有uic.exe 没有pyside2-uic.exe 去Scripts目录下查看就能找到