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

WPF实现一个带旋转动画的菜单栏

WPF实现一个带旋转动画的菜单栏

  • 一、创建WPF项目及文件
    • 1、创建项目
    • 2、创建文件夹及文件
    • 3、添加引用
  • 二、代码实现
    • 2.ControlAttachProperty类

一、创建WPF项目及文件

1、创建项目

打开VS2022,创建一个WPF项目,如下所示
在这里插入图片描述在这里插入图片描述

2、创建文件夹及文件

创建资源文件夹,添加字体图标文件,添加 Menu样式文件,如下所示
在这里插入图片描述
创建公共附加属性用控件类库,并创建对应的 ControlAttachProperty 类文件如下:
在这里插入图片描述
在这里插入图片描述

3、添加引用

右键 Menu_WPF 添加引用,将类库引用到当前项目
在这里插入图片描述

二、代码实现

2.ControlAttachProperty类

代码如下(示例):

using Microsoft.Win32;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using CheckBox = System.Windows.Controls.CheckBox;
using ComboBox = System.Windows.Controls.ComboBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
using RadioButton = System.Windows.Controls.RadioButton;
using RichTextBox = System.Windows.Controls.RichTextBox;
using TextBox = System.Windows.Controls.TextBox;namespace Common.UserControl.Extession
{/// <summary>/// 公共附加属性/// </summary>public static class ControlAttachProperty{#region FocusBorderBrush 焦点边框色,输入控件public static readonly DependencyProperty FocusBorderBrushProperty = DependencyProperty.RegisterAttached("FocusBorderBrush", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));public static void SetFocusBorderBrush(DependencyObject element, Brush value){element.SetValue(FocusBorderBrushProperty, value);}public static Brush GetFocusBorderBrush(DependencyObject element){return (Brush)element.GetValue(FocusBorderBrushProperty);}#endregion#region MouseOverBorderBrush 鼠标进入边框色,输入控件public static readonly DependencyProperty MouseOverBorderBrushProperty =DependencyProperty.RegisterAttached("MouseOverBorderBrush", typeof(Brush), typeof(ControlAttachProperty),new FrameworkPropertyMetadata(Brushes.Transparent,FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.Inherits));/// <summary>/// Sets the brush used to draw the mouse over brush./// </summary>public static void SetMouseOverBorderBrush(DependencyObject obj, Brush value){obj.SetValue(MouseOverBorderBrushProperty, value);}/// <summary>/// Gets the brush used to draw the mouse over brush./// </summary>[AttachedPropertyBrowsableForType(typeof(TextBox))][AttachedPropertyBrowsableForType(typeof(CheckBox))][AttachedPropertyBrowsableForType(typeof(RadioButton))][AttachedPropertyBrowsableForType(typeof(DatePicker))][AttachedPropertyBrowsableForType(typeof(ComboBox))][AttachedPropertyBrowsableForType(typeof(RichTextBox))]public static Brush GetMouseOverBorderBrush(DependencyObject obj){return (Brush)obj.GetValue(MouseOverBorderBrushProperty);}#endregion#region AttachContentProperty 附加组件模板/// <summary>/// 附加组件模板/// </summary>public static readonly DependencyProperty AttachContentProperty = DependencyProperty.RegisterAttached("AttachContent", typeof(ControlTemplate), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));public static ControlTemplate GetAttachContent(DependencyObject d){return (ControlTemplate)d.GetValue(AttachContentProperty);}public static void SetAttachContent(DependencyObject obj, ControlTemplate value){obj.SetValue(AttachContentProperty, value);}#endregion#region WatermarkProperty 水印/// <summary>/// 水印/// </summary>public static readonly DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached("Watermark", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(""));public static string GetWatermark(DependencyObject d){return (string)d.GetValue(WatermarkProperty);}public static void SetWatermark(DependencyObject obj, string value){obj.SetValue(WatermarkProperty, value);}#endregion#region FIconProperty 字体图标/// <summary>/// 字体图标/// </summary>public static readonly DependencyProperty FIconProperty = DependencyProperty.RegisterAttached("FIcon", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(""));public static string GetFIcon(DependencyObject d){return (string)d.GetValue(FIconProperty);}public static void SetFIcon(DependencyObject obj, string value){obj.SetValue(FIconProperty, value);}#endregion#region FIconSizeProperty 字体图标大小/// <summary>/// 字体图标/// </summary>public static readonly DependencyProperty FIconSizeProperty = DependencyProperty.RegisterAttached("FIconSize", typeof(double), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(12D));public static double GetFIconSize(DependencyObject d){return (double)d.GetValue(FIconSizeProperty);}public static void SetFIconSize(DependencyObject obj, double value){obj.SetValue(FIconSizeProperty, value);}#endregion#region FIconMarginProperty 字体图标边距/// <summary>/// 字体图标/// </summary>public static readonly DependencyProperty FIconMarginProperty = DependencyProperty.RegisterAttached("FIconMargin", typeof(Thickness), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));public static Thickness GetFIconMargin(DependencyObject d){return (Thickness)d.GetValue(FIconMarginProperty);}public static void SetFIconMargin(DependencyObject obj, Thickness value){obj.SetValue(FIconMarginProperty, value);}#endregion#region AllowsAnimationProperty 启用旋转动画/// <summary>/// 启用旋转动画/// </summary>public static readonly DependencyProperty AllowsAnimationProperty = DependencyProperty.RegisterAttached("AllowsAnimation", typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, AllowsAnimationChanged));public static bool GetAllowsAnimation(DependencyObject d){return (bool)d.GetValue(AllowsAnimationProperty);}public static void SetAllowsAnimation(DependencyObject obj, bool value){obj.SetValue(AllowsAnimationProperty, value);}/// <summary>/// 旋转动画刻度/// </summary>private static DoubleAnimation RotateAnimation = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(200)));/// <summary>/// 绑定动画事件/// </summary>private static void AllowsAnimationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){var uc = d as FrameworkElement;if (uc == null) return;if (uc.RenderTransformOrigin == new Point(0, 0)){uc.RenderTransformOrigin = new Point(0.5, 0.5);RotateTransform trans = new RotateTransform(0);uc.RenderTransform = trans;}var value = (bool)e.NewValue;if (value){RotateAnimation.To = 180;uc.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, RotateAnimation);}else{RotateAnimation.To = 0;uc.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, RotateAnimation);}}#endregion#region CornerRadiusProperty Border圆角/// <summary>/// Border圆角/// </summary>public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.RegisterAttached("CornerRadius", typeof(CornerRadius), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));public static CornerRadius GetCornerRadius(DependencyObject d){return (CornerRadius)d.GetValue(CornerRadiusProperty);}public static void SetCornerRadius(DependencyObject obj, CornerRadius value){obj.SetValue(CornerRadiusProperty, value);}#endregion#region LabelProperty TextBox的头部Label/// <summary>/// TextBox的头部Label/// </summary>public static readonly DependencyProperty LabelProperty = DependencyProperty.RegisterAttached("Label", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));[AttachedPropertyBrowsableForType(typeof(TextBox))]public static string GetLabel(DependencyObject d){return (string)d.GetValue(LabelProperty);}public static void SetLabel(DependencyObject obj, string value){obj.SetValue(LabelProperty, value);}#endregion#region LabelTemplateProperty TextBox的头部Label模板/// <summary>/// TextBox的头部Label模板/// </summary>public static readonly DependencyProperty LabelTemplateProperty = DependencyProperty.RegisterAttached("LabelTemplate", typeof(ControlTemplate), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));[AttachedPropertyBrowsableForType(typeof(TextBox))]public static ControlTemplate GetLabelTemplate(DependencyObject d){return (ControlTemplate)d.GetValue(LabelTemplateProperty);}public static void SetLabelTemplate(DependencyObject obj, ControlTemplate value){obj.SetValue(LabelTemplateProperty, value);}#endregion}
}

Menu样式文件实现

    <!--背景透明的HeaderItem样式,带旋转动画--><Style x:Key="TransparentHeaderMenuItem" TargetType="{x:Type MenuItem}"><Setter Property="BorderBrush" Value="{StaticResource MenuBorderBrush}"/><Setter Property="BorderThickness" Value="1"/><Setter Property="Background" Value="{StaticResource MenuBackground}"/><Setter Property="Foreground" Value="{StaticResource TextForeground}"/><Setter Property="FontSize" Value="{StaticResource FontSize}"/><Setter Property="Margin" Value="2,0,2,0"/><Setter Property="Height" Value="30"/><Setter Property="local:ControlAttachProperty.FIconSize" Value="18"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type MenuItem}"><Grid x:Name="Bg" VerticalAlignment="{TemplateBinding VerticalAlignment}"><StackPanel Orientation="Horizontal" x:Name="border" VerticalAlignment="Center" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"><!--icon--><TextBlock x:Name="PART_Icon" Text="{TemplateBinding Icon}" Foreground="{TemplateBinding Foreground}" local:ControlAttachProperty.AllowsAnimation="{Binding IsSubmenuOpen,RelativeSource={RelativeSource TemplatedParent}}"FontSize="{TemplateBinding local:ControlAttachProperty.FIconSize}" Style="{StaticResource FIcon}" /><TextBlock x:Name="txtHeader" Margin="5 0 0 0" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="Stretch" Text="{TemplateBinding Header}" VerticalAlignment="Center" Grid.Column="1" Foreground="{TemplateBinding Foreground}"/></StackPanel><!--弹出子集菜单容器--><Popup x:Name="SubMenuPopup" AllowsTransparency="true" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom"  Focusable="false" VerticalOffset="0"PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"><Border Background="{TemplateBinding Background}"  CornerRadius="0" Margin="5" Effect="{StaticResource DefaultDropShadow}"BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"><Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True"><StackPanel Margin="10" IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/></Grid></Border></Popup></Grid><!--触发器--><ControlTemplate.Triggers><!--高亮状态--><Trigger Property="IsHighlighted" Value="true"><Setter Property="Foreground" Value="{StaticResource MouseOverForeground}"></Setter></Trigger><Trigger Property="IsPressed" Value="true"><Setter Property="Foreground" Value="{StaticResource PressedForeground}"></Setter></Trigger><Trigger Property="IsEnabled" Value="False"><Setter TargetName="border" Value="{StaticResource DisableOpacity}" Property="Opacity"></Setter></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style>

MainWindow样式实现

  <Menu Width="80" Height="30" Margin="3" Background="Transparent" ><MenuItem Header="展开菜单" Style="{StaticResource TransparentHeaderMenuItem}" Padding="0" Icon="&#xe61b;" ><MenuItem Style="{StaticResource TransparentHeaderMenuItem}" Icon="&#xe605;" Header="设置" /><MenuItem Style="{StaticResource TransparentHeaderMenuItem}" Icon="&#xe656;" Header="插件管理" /><MenuItem Style="{StaticResource TransparentHeaderMenuItem}" Icon="&#xe65e;"  Header="用户管理" /><MenuItem Style="{StaticResource TransparentHeaderMenuItem}" Icon="&#xe659;" Header="修改密码" /><MenuItem Style="{StaticResource TransparentHeaderMenuItem}" Icon="&#xe7c6;" Header="在线更新" /><Separator Background="SpringGreen" Style="{StaticResource HorizontalSeparatorStyle}"/><MenuItem Style="{StaticResource TransparentHeaderMenuItem}" Icon="&#xe6d5;" Header="问题反馈" /><MenuItem Style="{StaticResource TransparentHeaderMenuItem}" Icon="&#xe65f;" Header="技术支持" /><MenuItem Style="{StaticResource TransparentHeaderMenuItem}" Icon="&#xe600;" Header="帮助" /><MenuItem Style="{StaticResource TransparentHeaderMenuItem}" Icon="&#xe622;" Header="关于" /></MenuItem></Menu>

相关文章:

WPF实现一个带旋转动画的菜单栏

WPF实现一个带旋转动画的菜单栏 一、创建WPF项目及文件1、创建项目2、创建文件夹及文件3、添加引用 二、代码实现2.ControlAttachProperty类 一、创建WPF项目及文件 1、创建项目 打开VS2022,创建一个WPF项目&#xff0c;如下所示 2、创建文件夹及文件 创建资源文件夹&…...

使用Dockerfile构建镜像

目录 1.使用Dockerfile构建tomcat镜像 1.1 通过ARG传参构建不同版本的tomcat 2.缩小镜像的体积大小 2.1 使用较小体积的基础镜像 2.2 多级构建减少体积 1.使用Dockerfile构建tomcat镜像 cd /opt mkdir tomcat cd tomcat/ 上传tomcat所需的依赖包 使用tar xf 解压三个压缩…...

概率论原理精解【3】

文章目录 向量值向量值函数导数对称矩阵定义性质例子应用 向量值理论基础定义性质应用示例 向量值函数的导数定义性质应用 向量值 向量值函数导数 D n ⊂ R n , 向量值函数 f : D n → R m D^n \subset R^n,向量值函数f:D^n\rightarrow R^m Dn⊂Rn,向量值函数f:Dn→Rm 1. 向量…...

[C/C++入门][循环]14、计算2的幂(2的n次方)

计算2的幂&#xff08;即2的n次方&#xff09;非常经典。你懂几种方法呢&#xff1f;很多人只会一种&#xff0c;我们来分析一下。 可以通过多种方式实现&#xff1a; 1、最简单的方法之一是使用位运算符<<&#xff0c;它本质上是在二进制表示下对2进行左移操作&#x…...

RPC与服务的注册发现

文章目录 1. 什么是远程过程调用(RPC)?2. RPC的流程3. RPC实践4. RPC与REST的区别4.1 RPC与REST的相似之处4.2 RPC与REST的架构原则4.3 RPC与REST的主要区别 5. RPC与服务发现5.1 以zookeeper为服务注册中心5.2 以etcd为服务注册中心 6. 小结参考 1. 什么是远程过程调用(RPC)?…...

3112. 访问消失节点的最少时间 Medium

给你一个二维数组 edges 表示一个 n 个点的无向图&#xff0c;其中 edges[i] [ui, vi, lengthi] 表示节点 ui 和节点 vi 之间有一条需要 lengthi 单位时间通过的无向边。 同时给你一个数组 disappear &#xff0c;其中 disappear[i] 表示节点 i 从图中消失的时间点&#xff0…...

FastAPI 学习之路(五十二)WebSockets(八)接受/发送json格式消息

前面我们发送的大多数都是text类型的消息&#xff0c;对于text消息来说&#xff0c;后端处理出来要麻烦的多&#xff0c;那么我们可以不可以传递json格式的数据&#xff0c;对于前后端来说都比较友好&#xff0c;答案是肯定的&#xff0c;我们需要做下处理。 首先&#xff0c;…...

Go语言并发编程-案例_3

案例 并发目录大小统计 业务逻辑 统计目录的文件数量和大小&#xff08;或其他信息&#xff09;。示例输出&#xff1a; // 某个目录&#xff1a;2637 files 1149.87 MB 实现思路 给定一个或多个目录&#xff0c;并发的统计每个目录的size&#xff0c;最后累加到一起。 当…...

pikachu之跨站脚本攻击(x‘s‘s)

1get型 输入a看一下 接着输入<a> 发现<>没有被过滤当做标签处理了 尝试在表单提交的框里面&#xff0c;输入xss语句 尝试输入<script>alert(1)</script> 发现有长度限制 因为这里是get请求 get请求的特点是&#xff1a;传参是在url中的 所以我们可以在…...

Qt模型/视图架构——委托(delegate)

一、为什么需要委托 模型&#xff08;model&#xff09;用来数据存储&#xff0c;视图&#xff08;view&#xff09;用来展示数据。因此&#xff0c;模型/视图架构是一种将数据存储和界面展示分离的编程方法。具体如下图所示&#xff1a; 由图可知&#xff0c;模型向视图提供数…...

python3.11SSL: SSLV3_ALERT_HANDSHAKE_FAILURE

参考&#xff1a;python request包 版本不兼容 报错sslv3 alert handshake failure 解决方法-CSDN博客 修改&#xff1a;Python311\Lib\site-packages\urllib3\util\ssl_.py 新版本3.11里默认没有DEFAULT_CIPHERS 补回来: #__imported from 3.6.8 # A secure default. # So…...

[深度学习]基于yolov10+streamlit目标检测演示系统设计

YOLOv10结合Streamlit构建的目标检测系统&#xff0c;不仅极大地增强了实时目标识别的能力&#xff0c;还通过其直观的用户界面实现了对图片、视频乃至摄像头输入的无缝支持。该系统利用YOLOv10的高效检测算法&#xff0c;能够快速准确地识别图像中的多个对象&#xff0c;并标注…...

开源模型应用落地-FastAPI-助力模型交互-进阶篇(三)

一、前言 FastAPI 的高级用法可以为开发人员带来许多好处。它能帮助实现更复杂的路由逻辑和参数处理&#xff0c;使应用程序能够处理各种不同的请求场景&#xff0c;提高应用程序的灵活性和可扩展性。 在数据验证和转换方面&#xff0c;高级用法提供了更精细和准确的控制&#…...

机器人及其相关工科专业课程体系

机器人及其相关工科专业课程体系 前言传统工科专业机械工程自动化/控制工程计算机科学与技术 新兴工科专业智能制造人工智能机器人工程 总结Reference: 前言 机器人工程专业是一个多领域交叉的前沿学科&#xff0c;涉及自然科学、工程技术、社会科学、人文科学等相关学科的理论…...

C#数字医学影像系统(RIS/PACS)源码,Oracle数据库,C/S架构,运行稳定

数字医学影像系统&#xff08;RIS/PACS&#xff09;源码&#xff0c;三甲以下的医院都能满足。PACS 系统全套成品源码。 开发技术&#xff1a;C/S架构&#xff0c;C#开发语言&#xff0c;数据库服务器采用Oracle数据库。 医学影像存储与传输系统&#xff0c;融合了医学信息化…...

Spring-Boot基础--yaml

目录 Spring-Boot配置文件 注意&#xff1a; YAML简介 YAML基础语法 YAML:数据格式 YAML文件读取配置内容 逐个注入 批量注入 ConfigurationProperties 和value的区别 Spring-Boot配置文件 Spring-Boot中不用编写.xml文件&#xff0c;但是spring-Boot中还是存在.prope…...

C/C++蓝屏整人代码

文章目录 &#x1f4d2;程序效果 &#x1f4d2;具体步骤 1.隐藏任务栏 2.调整cmd窗口大小 3.调整cmd窗口屏幕颜色 4.完整代码 &#x1f4d2;代码详解 &#x1f680;欢迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e; &#x1f680;关注博主&a…...

【Android安全】Ubuntu 下载、编译 、刷入Android-8.1.0_r1

0. 环境准备 Ubuntu 16.04 LTS&#xff08;预留至少95GB磁盘空间&#xff0c;实测占94.2GB&#xff09; Pixel 2 XL 要买欧版的&#xff0c;不要美版的。 欧版能解锁BootLoader、能刷机。 美版IMEI里一般带“v”或者"version"&#xff0c;这样不能解锁BootLoader、…...

HBuilder X3.4版本中使用uni-app自定义组件

HBuilder X3.4版本中使用uni-app自定义组件 这是我的小程序页面结构 方式一&#xff1a;导入components 1.创建componets文件&#xff0c;并编写你的组件页面 <template><view class"my-search-container"><!-- 使用 view 组件模拟 input 输入框的样…...

PHP基础语法(一)

一、初步语法 1、PHP代码标记&#xff1a;以 <?php 开始&#xff0c;以 ?> 结束&#xff1b; 2、PHP注释&#xff1a;行注释&#xff1a;//&#xff08;双斜杠&#xff09;或# 块注释&#xff1a;/* */ 3、PHP语句分隔符&#xff1a; 1&#xff09;在PHP中&#…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...