ITPub博客

首页 > 应用开发 > IT综合 > 这是一个 依赖属性从定义 → 使用 → 变化 → 影响 UI 的最小闭环示例,

这是一个 依赖属性从定义 → 使用 → 变化 → 影响 UI 的最小闭环示例,

投稿 IT综合 作者:ecclw459 时间:2026-01-29 16:21:55 0 删除 编辑

est ├─ MainWindow.xaml        # 界面声明:创建并使用 MyControl,在 XAML 中给依赖属性 MyTitle 赋初值 ├─ MainWindow.xaml.cs     # 行为逻辑:运行时修改 MyControl.MyTitle,触发依赖属性变化


using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; namespace Test {    public class MyControl : Control    {         static MyControl ()        {             // 指定默认样式,如果有自定义样式可以用这个            DefaultStyleKeyProperty.OverrideMetadata(                typeof(MyControl),                new FrameworkPropertyMetadata(typeof(MyControl)));        }        public static readonly DependencyProperty MyTitleProperty =            DependencyProperty.Register(                 "MyTitle" ,                       // 属性名                typeof( string ),               // 属性类型                typeof(MyControl),             // 所属类                new PropertyMetadata(         // 元数据                     "默认标题" ,               // 默认值                    new PropertyChangedCallback(OnMyTitleChanged)) // 改变回调            );        public string MyTitle        {            get => ( string )GetValue(MyTitleProperty);             set => SetValue(MyTitleProperty, value);        }         // 改变回调        private static void OnMyTitleChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)        {            var control = d as MyControl;             // 当属性变化时打印新值            System.Diagnostics.Debug.WriteLine($ "MyTitle 改变为:{e.NewValue}" );             // 更新主窗口标题             if (control != null)            {                 // 找到依赖属性所在的窗口                var window = Window.GetWindow(control);                 if (window != null)                {                    window.Title = e.NewValue?.ToString(); // 更新主窗口标题                }            }

using System; using System.Windows; namespace Test {     /// <summary>     /// MainWindow.xaml 的交互逻辑     /// </summary>    public partial class MainWindow : Window    {        public MainWindow ()        {            InitializeComponent();             // myControl 是 MainWindow.xaml 中定义的控件实例             // 对应创建的自定义控件 MyControl            myControl.MyTitle = "我是窗口" ;        }        private void Button_Click (object sender, RoutedEventArgs e)        {             // 点击按钮时更新依赖属性            myControl.MyTitle = textBox.Text;


   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:Test"        mc:Ignorable="d"        Title="MainWindow" Height="450" Width="800">        <StackPanel Margin="20">        <!-- 利用依赖属性生成一个自定义控件myControl -->        <!-- local:MyControl x:Name="myControl" => 在Test命名空间中找一个叫MyControl的类 -->        <!-- 这里的依赖属性是Title -->        <local:MyControl x:Name="myControl" MyTitle="初始标题" Height="50"/>        <!-- 一个文本框 -->        <TextBox x:Name="textBox" Margin="0,10,0,0" Height="30"/>        <!-- 一个按钮 -->

// 输入propdp,然后连续按两下Tab键,VS会帮我们自动生成下面的这段代码    public int MyProperty    {        get { return ( int )GetValue(MyPropertyProperty); }         set { SetValue(MyPropertyProperty, value); }    }     // Using a DependencyProperty as the backing store for MyProperty.       // This enables animation, styling, binding, etc...    public static readonly DependencyProperty MyPropertyProperty =        DependencyProperty.Register(         "MyProperty" ,        typeof( int ),

// 这个属性,名义上属于 MyControl 类型 DependencyProperty.Register(         "MyProperty" ,        typeof( int ),        typeof(MyControl),    ...) // 这个属性由 Grid 定义, 但可以附加到任何 DependencyObject 上   DependencyProperty.RegisterAttached(         "MyProperty" ,        typeof( int ),

// 输入propa,然后连续按两下Tab键,VS会帮我们自动生成下面的这段代码   public static int GetMyProperty (DependencyObject obj)    {         return ( int )obj.GetValue(MyPropertyProperty);    }    public static void SetMyProperty (DependencyObject obj, int value)    {        obj.SetValue(MyPropertyProperty, value);    }     // Using a DependencyProperty as the backing store for MyProperty.       //This enables animation, styling, binding, etc...    public static readonly DependencyProperty MyPropertyProperty =        DependencyProperty.RegisterAttached(             "MyProperty" ,            typeof( int ),

     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:TT"        mc:Ignorable="d"        Title="我不是标题" Height="450" Width="800">    <StackPanel Margin="20">        <PasswordBox x:Name="pwdBox"                     local:PasswordHelper.Password=""/>        <Button Content="读取密码"                Margin="0,10,0,0"                Click="Button_Click"/>


using System.Windows; namespace TT {     /// <summary>     /// MainWindow.xaml 的交互逻辑     /// </summary>    public partial class MainWindow : Window    {        public MainWindow ()        {            InitializeComponent();        }        private void Button_Click (object sender, RoutedEventArgs e)        {             // 获取附加属性值             string password = PasswordHelper.GetPassword(pwdBox);             // 消息弹窗打印

sing System.Windows; using System.Windows.Controls; namespace TT {    public static class PasswordHelper    {        public static readonly DependencyProperty PasswordProperty =            DependencyProperty.RegisterAttached(                 "Password" ,                typeof( string ),                typeof(PasswordHelper),                 // string.Empty相当于默认值 = ""                 // C/C++程序员请注意:C#中 "" ≠ null                 // new PropertyMetadata(string.Empty, OnPasswordChanged));                new PropertyMetadata(null, OnPasswordChanged));        public static string GetPassword (DependencyObject obj)        {             return ( string )obj.GetValue(PasswordProperty);        }        public static void SetPassword (DependencyObject obj, string value)        {            obj.SetValue(PasswordProperty, value);        }         // 改变回调        private static void OnPasswordChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)        {             if (d is PasswordBox passwordBox)            {                 // 同步到真实 Password                 if (passwordBox.Password != ( string )e.NewValue)                {                    passwordBox.Password = ( string )e.NewValue;                }                 // 注册事件(先移除,避免重复)                passwordBox.PasswordChanged -= PasswordBox_PasswordChanged;                passwordBox.PasswordChanged += PasswordBox_PasswordChanged;            }        }        private static void PasswordBox_PasswordChanged (object sender, RoutedEventArgs e)        {            var passwordBox = (PasswordBox)sender;            SetPassword(passwordBox, passwordBox.Password);

MVVM ├─ App.xaml                     # 应用入口:声明应用级资源并指定启动窗口 │ ├─ Views │  ├─ MainWindow.xaml           # 界面声明:定义 PasswordBox,并通过附加属性绑定 ViewModel 的 Password │  └─ MainWindow.xaml.cs        # 界面逻辑:初始化窗口并设置 DataContext │ ├─ ViewModel │  └─ VMod.cs       # 视图模型:定义 Password 状态并实现属性变更通知 │ └─ Helpers



    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:MVVM.Helpers"        mc:Ignorable="d"          Title="MainWindow" Height="450" Width="800">    <StackPanel Margin="20">        <PasswordBox            local:PasswordHelper.Password="{Binding Password, Mode=TwoWay}" />        <Button Content="读取密码"                Margin="0,10,0,0"


using MVVM.ViewModel; using MVVM.Helpers;www.juanyitang.com namespace MVVM.Views {     /// <summary>     /// Interaction logic for MainWindow.xaml     /// </summary>    public partial class MainWindow : Window    {        public MainWindow ()        {            InitializeComponent();            DataContext = new VMod();        }        private void Button_Click (object sender, RoutedEventArgs e)        {            var vm = (VMod)DataContext;            MessageBox.Show(vm.Password);

using System.Windows;mzdbt.com using System.Windows.Controls; namespace MVVM.Helpers {    public static class PasswordHelper    {        public static readonly DependencyProperty PasswordProperty =            DependencyProperty.RegisterAttached(                 "Password" ,                typeof( string ),fjhsws.cn                typeof(PasswordHelper),                new FrameworkPropertyMetadata(                     string .Empty,                     //null,                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,                    OnPasswordChanged));cerobj.com        public static void SetPassword (DependencyObject obj, string value)        { www.abouta.cn            obj.SetValue(PasswordProperty, value);        }        public static string GetPassword (DependencyObject obj)        {       abouta.cn       return ( string )obj.GetValue(PasswordProperty);        }        private static void OnPasswordChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)        {             if (d is not PasswordBox box)          0527999.com        return ;            box.PasswordChanged -= PasswordBox_PasswordChanged;             if (box.Password != ( string )e.NewValue)            {                box.Password = ( string )e.NewValue;              }shLnmp.com            box.PasswordChanged += PasswordBox_PasswordChanged;        }        private static void PasswordBox_PasswordChanged (object sender, RoutedEventArgs e)        {juanyitang.com            var box = (PasswordBox)sender;


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048957/viewspace-3109422/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2026-01-07

  • 博文量
    108
  • 访问量
    102109