WPF 用户控件依赖注入赋值

这篇具有很好参考价值的文章主要介绍了WPF 用户控件依赖注入赋值。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

我一直想组件化得去开发WPF,因为我觉得将复杂问题简单化是最好的

如何组件化开发

WPF 用户控件依赖注入赋值,WPF 入门知识,wpf

主窗口引用

<Window x:Class="WpfApp1.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:WpfApp1"
        xmlns:MD="http://materialdesigninxaml.net/winfx/xaml/themes"
        xmlns:Views="clr-namespace:WpfApp1.Views"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" >
    <Window.Resources>
        <Style x:Key="my_text" TargetType="TextBlock">
            <Setter Property="FontSize" Value="30" />
            <Setter Property="Margin" Value="8" />
        </Style>
    </Window.Resources>
    <Window.DataContext >
        <!--需要命名来指定数据源-->
        <local:MainWindowViewModel x:Name="viewModel"/>
    </Window.DataContext>
    <Grid>
        <!--不能直接写TitleValue,Binding数据源会有问题-->
        <Views:ViewA Margin="10"
                Title="{Binding ElementName=viewModel,Path=TitleValue}" />
    </Grid>
</Window>

cs部分

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class MainWindowViewModel
    {
        public string TitleValue { get; set; } =  "我是测试数据";

    }
}

控件窗口

    <UserControl.DataContext>
        <local:ViewAViewModel />
    </UserControl.DataContext>

    <Grid>
        <TextBlock Text="{Binding Title}" />
    </Grid>
/// <summary>
/// ViewA.xaml 的交互逻辑
/// </summary>
public partial class ViewA : UserControl
{

    public static readonly DependencyProperty TitleProperty;

    /// <summary>
    /// 为了拿到数据源需要定义一下
    /// </summary>
    private ViewAViewModel ViewModel = new ViewAViewModel();
    public ViewA()
    {
        InitializeComponent();
        ViewModel = (ViewAViewModel)DataContext;

    }
    static ViewA()
    {
        //静态构造
        TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(ViewA),new PropertyMetadata("",
            new PropertyChangedCallback((item, res) =>
            {
                //拿到数据,再次赋值
                var model =(ViewA)item;
                model.ViewModel.Title = (string)res.NewValue;
            })));
    }

    /// <summary>
    /// 只是为了有代码提示,添加依赖属性后不会被调用
    /// </summary>

    public string Title { get; set; }




}
public partial class ViewAViewModel : ObservableObject
{
    /// <summary>
    /// 通知更新
    /// </summary>
    [ObservableProperty]
    private string title = "ViewA Title!";

}

依赖注入代码优化

我将复杂的依赖注入的代码进行了优化,减少了重复内容的输入。

//原代码
TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(ViewA), new PropertyMetadata(default,
  new PropertyChangedCallback((item, res) =>
  {
      //拿到数据,再次赋值
      var model = (ViewA)item;
      model.ViewModel.Title = (string)res.NewValue;
  })));

//新代码

 TitleProperty = DependencyPropertySet<ViewA, string>("Title", (view, value) =>
 {
     view.ViewModel.Title = value;
 });


/// <summary>
/// 简化依赖注入代码
/// </summary>
/// <typeparam name="View"></typeparam>
/// <typeparam name="Value"></typeparam>
/// <param name="name"></param>
/// <param name="action"></param>
/// <returns></returns>
public static DependencyProperty DependencyPropertySet<View,Value>(string name,Action<View,Value> action) 
    where View : class 
{
    var res=  DependencyProperty.Register(name, typeof(Value), typeof(View), new PropertyMetadata(default,
        new PropertyChangedCallback((item, res) =>
        {
            var model = item as View;
            var value = (Value)res.NewValue;
            if(model != null)
            {
                action(model, value);
            }else
               {
                   throw new Exception("model value is null");
               }
        })));
    return res;
}



更新2023年12月9日

我现在依赖属性扩展封装在一个静态文件里面

namespace BlankApp1.Utils
{
    public class MyWpfExtension<View> where View : class
    {
        
        
        /// <summary>
        /// 简化依赖注入代码
        /// </summary>
        /// <typeparam name="View"></typeparam>
        /// <typeparam name="Value"></typeparam>
        /// <param name="name"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public DependencyProperty DependencyPropertySet<Value>(string name, Action<View, Value> action)
        {
            var res = DependencyProperty.Register(name, typeof(Value), typeof(View), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                new PropertyChangedCallback((item, res) =>
                {
                    var model = item as View;
                    var value = (Value)res.NewValue;
                    if (model != null)
                    {
                        action(model, value);
                    }
                    else
                    {
                        throw new Exception("model value is null");
                    }
                })));
            return res;
        }

    }
}

简化后的依赖注入

记得UserControl.xaml里面绑定你ViewModel。这样的话有代码提示

    <UserControl.DataContext>
    	<!--选择你自己的ViewModel-->
        <ViewModels:TitileViewModel />
    </UserControl.DataContext>
namespace BlankApp1.Views
{
    /// <summary>
    /// TitleView.xaml 的交互逻辑
    /// </summary>
    public partial class TitleView : UserControl
    {

        //这个只是为了代码提示,不涉及逻辑。属性类型按照需求更改。
        public MainWindow MainWindow { get; set; }

        //初始化依赖属性构造器
        public  static readonly MyWpfExtension<TitleView> MyWpfExtension = new MyWpfExtension<TitleView>();

        //这个是简化后的依赖属性
        public static readonly DependencyProperty MainWindowProperty = 
            MyWpfExtension.DependencyPropertySet<MainWindow>("MainWindow", (view, value) =>
        {
            view.TitileViewModel.MainWindow = value;
        });

        /// <summary>
        /// DataContext的数据
        /// </summary>
        public TitileViewModel TitileViewModel { get; set; }

        public TitleView()
        {
            InitializeComponent();
            //拿到DataContext数据重定向
            TitileViewModel = (TitileViewModel)DataContext;
            TitileViewModel.UserName = "小王";
        }
    }
}

结尾

我后面要根据Vue的单向数据流,来构思WPF 父子组件如何搭建。其实关键的就是数据流的问题。根据Vue的单向数据流,父组件直接设置子组件的属性,子组件通过回调函数回调变化。我打算写个项目实战一下。

WPF仿网易云 CSDN 博客专栏

WPF 用户控件依赖注入赋值,WPF 入门知识,wpf文章来源地址https://www.toymoban.com/news/detail-722531.html

到了这里,关于WPF 用户控件依赖注入赋值的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【目标检测】-入门知识

    回归问题 是指给定输入变量(特征)和一个连续的输出变量(标签),建立一个函数来预测输出变量的值。换句话说,回归问题的目标是预测一个连续的输出值,例如预测房价、股票价格、销售额等。回归问题通常使用回归分析技术,例如线性回归、多项式回归、决策树回归

    2024年04月15日
    浏览(25)
  • TensorFlow入门知识

    TensorFlow是集齐了很多深度学习相关的算法的框架,你可以利用他搭建自己的神经网络模型。对于开发者来说,告诉TensorFlow一批特征数据和最终的答案数据,让其通过一个神经网络模型进行训练,最终输出模型。模型将应用于应用端,给他一个输入特征值,就能预测出一个答

    2024年02月08日
    浏览(30)
  • 第一讲:入门知识笔记

    python 变量无类型,但值里面有类型。 动态类型语言(pythonjavascript) Subtraction reverse 3-digit number 判断两个浮点数是否相等不能直接用== 运算优先级 operation precedence not and or 计算闰年 交换变量 name variable google.github.io/styleguide/pyguide.html python中的权限控制access control 默认成员变量

    2024年01月25日
    浏览(32)
  • Hadoop详细入门知识

    1.1 大数据的概念 最近几年,IT行业最火的名词中,少不了\\\"大数据\\\"、“人工智能”、“云计算”、“物联网”、\\\"区块链\\\"等等这些名词。针对于**“大数据”**这个名词,现在更是全国老百姓,老少皆知的一个词语。但是什么是大数据,除了IT行业的专业人士外,其他人乃至其

    2024年02月07日
    浏览(28)
  • 认识Transformer:入门知识

    视频链接: https://www.youtube.com/watch?v=ugWDIIOHtPAlist=PLJV_el3uVTsOK_ZK5L0Iv_EQoL1JefRL4index=60 Seq2Seq RNN不容易被平行化 提出用CNN来代替RNN,CNN 可以平行化,但是需要的层数比较深,才能看完所有的输入内容。 Self-Attention layer b1 到b4 是可以同时被算出。 可以用来取代RNN。 来源: Attentio

    2024年02月12日
    浏览(29)
  • Java基础入门知识

    以下是学习java必备的知识 目录 前言 一、Java入门 二、基本数据类型与数组 标识符与 2. 基本数据类型 3. 类型转换运算 4. 运算符 5. 数组 6.控制结构(与c使用一致) 总结 Java语言是面向对象编程语言,编写的软件与平台无关。具有语法简单、面向对象、稳定、与平台无

    2024年02月16日
    浏览(44)
  • 学习web入门知识汇总

    第一章 WEB简介 web流程:输入网站访问网站之后向服务器发送请求,与数据库交互后经服务器返回请求结果,返回给用户。 浏览器工作原理:通过域名获取web服务器IP地址(DNS解析);访问web服务器。 web主要用到的技术:html、javescript、css. URL的详细格式:schema://host[:port#]/p

    2024年02月07日
    浏览(31)
  • 【C++】C++入门知识

    😁作者:日出等日落 🔔专栏:C++ 不要去等谁,所有的不期而遇都在路上。   C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等。熟悉C语言之后,对C++学习有一定的帮助 本章节主要目标: 1. 补充C语言语法的不足,以及C++是如何对

    2024年02月05日
    浏览(32)
  • C++ 进制转化入门知识(1)

    进制是一种用来表示数值的系统或方法,它是基于一个特定的基数来工作的。在我们常见的几种进制中,有: 1. **二进制(基数 2)**:    二进制只用两个数字:0和1。这是计算机内部使用的数制系统,因为计算机的基本单元(比特)只有两种状态:0或1。 2. **十进制(基数

    2024年02月09日
    浏览(29)
  • 【C ++】C++入门知识(二)

    作者:小卢 专栏:《C++》 喜欢的话:世间因为少年的挺身而出,而更加瑰丽。 ——《人民日报》 1.1.引用的概念及应用 引用() 引用不是新定义一个变量,而是给已存在变量取了一个别名 它和它引用的变量共用同一块内存空间 类型 引用变量名(对象名) = 引用实体; 引用在

    2024年02月02日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包