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

WPF学习(四)

文章目录

  • 一、用户控价
    • 1.1 依赖属性的注册
    • 1.2 具体使用

一、用户控价

1.1 依赖属性的注册

using System.Windows;
using System.Windows.Controls;namespace WpfApp
{public partial class MyUserControl : UserControl{// 依赖属性:外部可绑定的文本public static readonly DependencyProperty TextProperty =DependencyProperty.Register("Text",typeof(string),typeof(MyUserControl),new FrameworkPropertyMetadata(string.Empty,FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,OnTextPropertyChanged));public string Text{get => (string)GetValue(TextProperty);set => SetValue(TextProperty, value);}// 自定义事件:提交按钮点击public static readonly RoutedEvent SubmitClickedEvent =EventManager.RegisterRoutedEvent("SubmitClicked",RoutingStrategy.Bubble,typeof(RoutedEventHandler),typeof(MyUserControl));public event RoutedEventHandler SubmitClicked{add => AddHandler(SubmitClickedEvent, value);remove => RemoveHandler(SubmitClickedEvent, value);}public MyUserControl(){InitializeComponent();DataContext = new MyUserControlViewModel(this);}private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){var control = (MyUserControl)d;control.RaiseEvent(new RoutedEventArgs(SubmitClickedEvent));}}
}

这段代码是在WPF中注册依赖属性(Dependency Property) 的标准写法,下面来详细解释它的作用和参数含义:

1. 函数整体作用
DependencyProperty.Register 是WPF中创建依赖属性的核心方法。它做了两件事:

  • 定义属性元数据:包括属性名称、类型、所有者类型、默认值等。
  • 返回属性标识符:通过静态字段(如 TextProperty)保存,用于后续通过 GetValue/SetValue 访问属性值。

2. 参数详解

public static readonly DependencyProperty TextProperty =DependencyProperty.Register("Text",                  // 参数1:属性名称(字符串)typeof(string),          // 参数2:属性类型(Type)typeof(MyUserControl),   // 参数3:所有者类型(Type)new FrameworkPropertyMetadata(  // 参数4:元数据string.Empty,    // 默认值FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,  // 绑定模式OnTextPropertyChanged  // 值变更回调));

参数1:“Text”

  • 含义:这是依赖属性的名称,必须与CLR包装器属性名一致(即类中的 public string Text { get; set; })。
  • 作用:WPF内部通过这个名称识别属性,例如在XAML中使用 <MyUserControl Text="Hello" />

参数2:typeof(string)

  • 含义:属性的类型,这里是字符串类型。
  • 作用:确保属性值类型安全,WPF会自动进行类型检查。

参数3:typeof(MyUserControl)

  • 含义:声明该依赖属性的所有者类型,即哪个类拥有这个属性。
  • 作用:允许同一个依赖属性被多个类共享(通过 AddOwner 方法),但这里 MyUserControl 是原始所有者。

参数4:FrameworkPropertyMetadata

  • 默认值(string.Empty):属性未被显式设置时的默认值。
  • 绑定模式(BindsTwoWayByDefault)
    • 表示此属性的默认绑定模式是双向绑定(Mode=TwoWay)。
    • 例如:<MyUserControl Text="{Binding SomeValue}" /> 会自动成为双向绑定。
  • 回调方法(OnTextPropertyChanged)
    • 当属性值变化时,WPF会自动调用这个静态方法。
    • 常用于实现属性变更通知或依赖操作。

3. 参数"Text"属于谁?
参数 "Text"MyUserControl 类的公共属性。通过依赖属性机制,这个属性:

  1. 可在XAML中直接使用
    <local:MyUserControl Text="直接设置值" />
    
  2. 支持数据绑定
    <local:MyUserControl Text="{Binding ViewModelProperty}" />
    
  3. 可通过代码访问
    myUserControl.Text = "通过代码设置";
    

4. 依赖属性 vs 普通属性

特性普通属性依赖属性
存储方式实例字段(如 private string _text由WPF属性系统统一管理
默认值在构造函数中设置通过元数据设置(全局唯一)
数据绑定需要手动实现 INotifyPropertyChanged原生支持,自动通知
样式/动画支持不支持支持(可被样式覆盖、可动画化)
继承性部分属性支持值继承(如 FontSize

※※※
5. 完整工作流程

  1. 注册阶段

    • 通过 DependencyProperty.Register 创建属性定义。
    • 静态字段 TextProperty 保存属性标识符。
  2. CLR包装器(可选但推荐):

    public string Text
    {get => (string)GetValue(TextProperty);set => SetValue(TextProperty, value);
    }
    
  3. 使用阶段

    • XAML中:<MyUserControl Text="值" />
    • 代码中:myControl.Text = "值";
    • 数据绑定时:WPF通过 TextProperty 标识符解析属性。

总结

  • “Text” 参数:是 MyUserControl 类的公共属性名,用于外部访问。
  • 依赖属性机制:让属性具备动态值解析、数据绑定、样式支持等高级特性,是WPF控件开发的核心技术。

1.2 具体使用

MainWindow.xaml

<Window x:Class="WpfApp2.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:WpfApp2"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><StackPanel><local:UserControl1 Margin="10" Height="200" Width="250" x:Name="userControl"/><Button Content="button1" Click="Button_Click_1"/><Button Content="button2" Click="Button_Click_2"/></StackPanel></Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 WpfApp2
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void Button_Click_1(object sender, RoutedEventArgs e){userControl.Text = "你大爷";}private void Button_Click_2(object sender, RoutedEventArgs e){userControl.Text = "你 好";}}
}

UserControl1.xaml

<UserControl x:Class="WpfApp2.UserControl1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp2"mc:Ignorable="d" d:DesignHeight="100" d:DesignWidth="200"><Grid><TextBox x:Name="txtInput" Margin="10" /><Button Content="提交" Click="Button_Click" Margin="10,50,10,10" /><TextBlock x:Name="lblOutput" Margin="10,90,10,10" /></Grid>
</UserControl>

UserControl1.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 WpfApp2
{/// <summary>/// UserControl1.xaml 的交互逻辑/// </summary>public partial class UserControl1 : UserControl{public UserControl1(){InitializeComponent();}private void Button_Click(object sender, RoutedEventArgs e){lblOutput.Text = "你输入的是:" + txtInput.Text;}public static readonly DependencyProperty TextProperty =DependencyProperty.Register("Text",                // 属性名typeof(string),        // 属性类型typeof(UserControl1), // 所有者类型new PropertyMetadata(  // 元数据string.Empty,      // 默认值OnTextPropertyChanged  // 值变更回调));public string Text{get => (string)GetValue(TextProperty);set => SetValue(TextProperty, value);}private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){var control = (UserControl1)d;control.lblOutput.Text = "属性值:" + e.NewValue;}}
}
http://www.dtcms.com/a/266534.html

相关文章:

  • 分布式集合通信--学习笔记
  • ComfyUI工作流:一键换背景体验不同场景
  • 如何搭建 OLAP 系统?OLAP与数据仓库有什么关系?
  • 2-2 PID-代码部分
  • Fiddler 中文版怎么配合 Postman 与 Wireshark 做多环境接口调试?
  • Hawk Insight|美国6月非农数据点评:情况远没有看上去那么好
  • 如何将FPGA设计验证效率提升1000倍以上(2)
  • 应急响应靶场——web2——知攻善防实验室
  • 大带宽服务器中冗余技术的功能
  • 新能源汽车功率级测试自动化方案:从理论到实践的革命性突破
  • Python常用医疗AI库以及案例解析(2025年版、上)
  • Nginx + ModSecurity + OWASP CRS + Lua + GEOIP2 构建传统WAF
  • 【ACP】阿里云云计算高级运维工程师--ACP
  • 服务器的IO性能怎么看?
  • 【机器学习3】机器学习(鸢尾花分类)项目核心流程与企业实践差异分析
  • 【问题记录】MySQL错误1140深度解析:聚合查询中的GROUP BY问题解决方案
  • PP-OCR:一款实用的超轻量级OCR系统
  • LINUX74 LAMP5
  • Poetry 在 Linux 和 Windows 系统中的安装步骤
  • 基于开源AI智能名片链动2+1模式S2B2C商城小程序的超级文化符号构建路径研究
  • WPF学习笔记(23)Window、Page与Frame、ViewBox
  • OneCode采用虚拟DOM结构实现服务端渲染的技术实践
  • 负载均衡--四层、七层负载均衡的区别
  • java中this. 和 this::的区别和用法
  • Apache RocketMQ进阶之路阅读笔记和疑问
  • RabbitMQ用法的6种核心模式全面解析
  • 论文解析:AutoMedPrompt框架的核心与实现示例
  • 【Qt】在windows环境下,配置QtCreator中的clang-format
  • P/Invoke 在默认封送(marshalling)规则下,常见托管 ⇄ 非托管类型的对应关系
  • Jenkins-Publish HTML reports插件