WPF仿网易云搭建笔记(2):组件化开发

文章目录

  • 前言
  • 专栏和Gitee仓库
  • 依赖属性
  • 实战:缩小,全屏,关闭按钮
    • 依赖属性操作封装
    • 主窗口传递this本身给TitleView标题控件
    • 主要代码
      • MainWindow.xmal
      • MainWindow.cs
      • 依赖属性方法封装
      • TitleView.cs
      • TitleViewModel
      • TitleViewModel
      • 实现效果

前言

这次我们来讲解一下WPF 的组件化开发流程,组件化开发是是可以极大降低我们页面开发难度,降低代码耦合的方法。这让我们可以将任意WPF界面进行拆解。因为我写过Vue,所以我会按照Vue的逻辑将WPF进行组件化开发。

专栏和Gitee仓库

WPF仿网易云 Gitee仓库

WPF仿网易云 CSDN博客专栏

依赖属性

WPF为了提高性能,限制了Binding的使用。需要将属性提前注册为依赖属性或者附加属性,才能解决使用Binding语法。原因是每个能binding的属性需要在内存中开辟存储空间。WPF默认不能Binding,需要主动声明才可以。

这个就是为什么Elelctron,Fullter等内存开销那么大,是因为他们的将可能没用的的内存空间也设置了。

博客园 痕迹g WPF依赖属性详解

B站 十月的寒流 WPF 中依赖属性及附加属性的概念及用法

B站 微软系列技术教程 WPF依赖属性详解

实战:缩小,全屏,关闭按钮

这里我讲解一下Window和UserControl两者的区别。Window就是整个窗口,UserControl就是控件。Window负责窗口的一些方法,比如拖拽,缩小放大。而我们是组件化开发,我们就需要将主窗口的this传给子组件

依赖属性操作封装

这里先去看我这个总结的博客。

WPF 用户控件依赖属性赋值

主窗口传递this本身给TitleView标题控件

因为我们是View和ViewModel开发,所有的View只有传递参数和暴露依赖属性的作用,实际的业务是ViewModel去做的。
所以我们传递的方向是

MainWindow
MainWindowViewModel
TitleView的MainWindow依赖属性
TitleViewModel的MainWindow

主要代码

MainWindow.xmal


<Window x:Class="BlankApp1.Views.MainWindow"......><!--需要主动设置名称,不然会Binding错误--><Window.DataContext><ViewModels:MainWindowViewModel x:Name="MainWindowViewModel" /></Window.DataContext><DockPanel LastChildFill="True"><!--其它代码--><Grid DockPanel.Dock="Top"MouseLeftButtonDown="Grid_MouseLeftButtonDown"Height="auto"><!--手动指定DataContext--><Views:TitleView  MainWindow="{Binding MainWindow, ElementName=MainWindowViewModel}"  /></Grid></DockPanel>
</Window>

MainWindow.cs

    public partial class MainWindow : Window{public MainWindowViewModel ViewModel { get; set; }public MainWindow(){InitializeComponent();//重定向ViewModelViewModel = (MainWindowViewModel)DataContext;ViewModel.MainWindow = this;}}

依赖属性方法封装

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;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;}}
}

TitleView.cs


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) =>{//通过依赖属性来获取MainWindow的对象view.TitileViewModel.MainWindow = value;});/// <summary>/// DataContext的数据/// </summary>public TitileViewModel TitileViewModel { get; set; }public TitleView(){InitializeComponent();//拿到DataContext数据重定向TitileViewModel = (TitileViewModel)DataContext;}}
}

TitleViewModel

using BlankApp1.Models;
using BlankApp1.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows;namespace BlankApp1.ViewModels
{public partial class TitileViewModel:ObservableObject{public RelayCommand CloseWindow { get; set; }public RelayCommand MaxOrNormalWindow { get; set; }public RelayCommand MiniWindow { get; set; }public MainWindow MainWindow { get; set; }public TitileViewModel() {//.......其它代码CloseWindow = new RelayCommand(() => {MainWindow.Close();Debug.WriteLine("关闭窗口");});MaxOrNormalWindow = new RelayCommand(() => {if(MainWindow.WindowState == WindowState.Normal){MainWindow.WindowState = WindowState.Maximized;MainWindow.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;MainWindow.MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;}else{MainWindow.WindowState = WindowState.Normal;}Debug.WriteLine("最大化或正常窗口");});MiniWindow = new RelayCommand(() => {MainWindow.WindowState = WindowState.Minimized;Debug.WriteLine("缩小窗口");});}}
}

TitleViewModel

就是绑定按钮事件,我就不放了
详细代码看我的Gitee仓库地址

WPF仿网易云 Gitee仓库

实现效果

在这里插入图片描述

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

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

相关文章

有什么好用的资产设备管理系统?工单管理系统在设备管理上有什么作用?

设备管理对于企业而言是非常重要的&#xff0c;像互联网企业、医院、化工企业、制造企业等&#xff0c;都需要用到贵重设备或者仪器。这些设备仪器不仅本身造价成本高&#xff0c;还和生产活动息息相关&#xff0c;所以必须做好日常的维护管理才能确保企业生产活动正常进行。而…

计算机网络:物理层(三种数据交换方式)

今天又学到一个知识&#xff0c;加油&#xff01; 目录 前言 一、电路交换 二、报文交换 三、分组交换 1、数据报方式 2、虚电路方式 3、比较 总结 前言 为什么要进行数据交换&#xff1f; 一、电路交换 电路交换原理&#xff1a;在数据传输期间&#xff0c;源结点与…

新手HTML和CSS的常见知识点

​​​​ 目录 1.HTML标题标签&#xff08;到&#xff09;用于定义网页中的标题&#xff0c;并按照重要性递减排列。例如&#xff1a; 2.HTML段落标签&#xff08;&#xff09;用于定义网页中的段落。例如&#xff1a; 3.HTML链接标签&#xff08;&#xff09;用于创建链接…

【网络编程之初出茅庐】

前言&#xff1a;本章主要先讲解一些基本的网络知识&#xff0c;先把基本的知识用起来&#xff0c;后续会更深入的讲解底层原理。 网络编程的概念 网络编程&#xff0c;指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信&#xff08;或称为网络数…

深度学习 Day16——P5运动鞋识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 文章目录 前言1 我的环境2 代码实现与执行结果2.1 前期准备2.1.1 引入库2.1.2 设置GPU&#xff08;如果设备上支持GPU就使用GPU,否则使用C…

【数据结构第 6 章 ④】- 用 C 语言实现图的深度优先搜索遍历和广度优先搜索遍历

目录 一、深度优先搜索 1.1 - 深度优先搜索遍历的过程 1.2 - 深度优先搜索遍历的算法实现 二、广度优先搜索 2.1 - 广度优先搜索遍历的过程 2.2 - 广度优先搜索遍历的算法实现 和树的遍历类似&#xff0c;图的遍历也是从图中某一顶点出发&#xff0c;按照某种方法对图中所…

VUE-脚手架搭建

文章目录 一、概述二、前提准备1. 安装 node-js2. npm 镜像设置3. 安装 vs-code 三、脚手架搭建1. Vue-2 搭建1. Vue-3 搭建 一、概述 官网&#xff1a;http://cn.vuejs.org/ vue 有两个大版本&#xff0c;分别是 vue-2 和 vue-3&#xff0c;目前新项目的话用 vue-3 的会比较多…

Jmeter,提取响应体中的数据:正则表达式、Json提取器

一、正则表达式 1、线程组--创建线程组&#xff1b; 2、线程组--添加--取样器--HTTP请求&#xff1b; 3、Http请求--添加--后置处理器--正则表达式提取器&#xff1b; 4、线程组--添加--监听器--查看结果树&#xff1b; 5、线程组--添加--取样器--调试取样器。 响应体数据…

正则表达式详解

什么是正则表达式 正则表达式&#xff0c;又称规则表达式&#xff0c;通常被用来检索、替换那些符合某个模式(规则)的文本。 正则表达式是对字符串操作的一种逻辑公式&#xff0c;就是用事先定义好的一些特定字符、及这些特定字符的组合&#xff0c;组成一个"规则字符串…

Docker-consule 服务发现与注册

consul服务更新和服务发现 什么是服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服务的压力承载&#xff0c;服务之间调用单纯的通过接口访问。直到后来出现了多个节点的分布式架构&…

Redis新数据类型-Bitmaps

目录 Bitmaps 简介 命令 1. setbit (1) 格式 (2) 实例 2. getbit (1) 格式 (2) 实例 3. bitcount (1) 格式 (2) 实例 4. bitop (1) 格式 (2) 实例 我的其他博客 Bitmaps 简介 Bitmaps 是 Redis 的一种新数据类型&#xff0c;它是一种用于存储位信息的数据结构&…

Dockerfile创建镜像--LNMP+wordpress

实验准备&#xff1a; nginx&#xff1a;172.111.0.10 docker-nginx mysql&#xff1a;172.111.0.20 docker-mysql php&#xff1a;172.111.0.30 docker-php 自定义网段&#xff1a;172.111.0.0/16mkdir nginx mysql php mv nginx-1.22.0.tar.gz wordpress-6.4.2-zh_CN.ta…

用postman进行web端自动化测试

前言 概括说一下&#xff0c;web接口自动化测试就是模拟人的操作来进行功能自动化&#xff0c;主要用来跑通业务流程。 主要有两种请求方式&#xff1a;post和get&#xff0c;get请求一般用来查看网页信息&#xff1b;post请求一般用来更改请求参数&#xff0c;查看结果是否正…

网络服务IP属地发生变化的原因有哪些?

近期&#xff0c;许多用户发现自己的网络服务IP属地发生了变化。原本固定的IP地址不再是静态的&#xff0c;而是发生了变动。这一现象引起了广大用户的关注和疑惑&#xff0c;对网络服务的使用和信息安全产生了影响。为了解决用户的疑虑&#xff0c;我们对此现象进行了深入探究…

2023.12.15 FineBI与kettle

1.结构化就是可以用schema描述的数据,就是结构化数据,能转为二维表格, 如CSV,Excel, 2.半结构化就是部分可以转换为二维表格,如JSON,XML 3.非结构化数据,就是完全无法用二维表格表示的数据,如Word文档,Mp4,图片,等文件. kettle的流程 新建转换-构建流图-配置组件-保存运行 使…

20.Java程序设计-基于SSM框架的安卓掌上校园生活系统的设计与实现

摘要&#xff1a; 随着移动互联网技术的快速发展&#xff0c;校园生活信息化成为提高学校管理效率、方便学生生活的关键。本研究以基于SSM&#xff08;Spring Spring MVC MyBatis&#xff09;框架的技术体系为基础&#xff0c;致力于设计与实现一款功能强大、高效稳定的安卓…

【EventBus】EventBus源码浅析

二、EventBus源码解析 目录 1、EventBus的构造方法2、订阅者注册 2.1 订阅者方法的查找过程2.2 订阅者的注册过程1. subscriptionsByEventType 映射&#xff1a;2. typesBySubscriber 映射&#xff1a;2.3 总结订阅者的注册过程 3、事件的发送 3.1 使用Post提交事件3.2 使用p…

飞天使-docker知识点8-docker的资源限制

文章目录 容器资源限制示例 容器资源限制 Docker提供了多种资源限制的方式&#xff0c;可以根据应用程序的需求和系统资源的可用性进行选择。以下是一些常见的Docker资源限制及其使用情况&#xff1a;CPU限制&#xff1a;通过设置CPU的配额&#xff08;quota&#xff09;和周期…

【Redis】深入理解 Redis 常用数据类型源码及底层实现(1.结构与源码概述)

在文章【Redis】不卡壳的 Redis 学习之路&#xff1a;从十大数据类型开始入手中我们介绍了Redis常用的10大数据类型&#xff0c;这10大数据类型可并不是直接在底层通过代码实现的&#xff0c;而是通过不同的底层数据结构组合起来的&#xff0c;这篇我们介绍下Redis常用数据类型…

轻量封装WebGPU渲染系统示例<45>- 材质组装流水线(MaterialPipeline)灯光、阴影、雾(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/MaterialPipelineFog.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如下&#xff1a; export class MaterialPipelineFog {pr…