当前位置: 首页 > article >正文

【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();
		 // 用一个自定义对象来持有数据DataContext
         this.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.kler.cn/a/325510.html

相关文章:

  • MySQL 事务
  • 【Block总结】掩码窗口自注意力 (M-WSA)
  • Linux第二课:LinuxC高级 学习记录day04
  • FreeType 介绍及 C# 示例
  • 【15】Word:互联网发展状况❗
  • docker 部署 MantisBT
  • MATLAB绘图基础
  • 利用 PostgreSQL 构建 RAG 系统实现智能问答
  • 小程序视频编辑SDK解决方案,轻量化视频制作解决方案
  • 三菱PLC数据 转 profinet IO项目案例
  • 使用 Docker 部署 RStudio 的终极教程
  • Spring Boot 点餐系统:一键订餐解决方案
  • C++之Person类中调用Date类
  • 电脑使用adb工具连接手机,全文完整教程
  • MFC - 常用基础控件
  • 高防服务器如何抵御网络攻击?
  • RT-DETR改进策略:BackBone改进|PoolFormer赋能RT-DETR,视觉检测性能显著提升的创新尝试
  • 11.C++程序中的常用函数
  • 【含文档】基于Springboot+Vue的个性化推荐电商平台(含源码+数据库+lw)
  • 【网络安全】公钥密码体制
  • 关于QSizeGrip在ui界面存在布局的情况下的不显示问题
  • 绿色新纪元:光伏技术飞跃与能源体系重塑
  • keil仿真||示波器的使用
  • unixODBC编程(三)查询数据库表中的数据
  • LangChain:构建复杂 NLP 应用的框架
  • ENV | docker 安装使用(简单实操版)