开始使用Panuon开源界面库环境配置并手写VS2019高仿界面
- 1. Panuon环境配置
- 1.1. 通过Nuget 安装 Panuon.WPF.UI
- 1.2. xaml引用命名空间
- 1.3. using Panuon.WPF.UI;
- 2. VS2019 view
- 2.1. 设置窗体尺寸和title
- 2.2. 添加静态资源
- 2.2.1. 什么是静态资源
- 2.3. 主Grid
- 2.3.1. 盒子模型
- 2.3.2. 嵌套布局
- 3. 总结
1. Panuon环境配置
1.1. 通过Nuget 安装 Panuon.WPF.UI
现在最新的是1.2.4.9,点击安装即可
1.2. xaml引用命名空间
修改MainWindow.xaml,引用命名空间xmlns:pu="clr-namespace:Panuon.WPF.UI;assembly=Panuon.WPF.UI"
然后把Window标签改为pu:WindowX
1.3. using Panuon.WPF.UI;
在MainWindow.cs中引用命名空间using Panuon.WPF.UI;
同样,需要把基类Window 改为 WindowX, 这样窗体变成了Panuon 窗体了,很简单。
2. VS2019 view
下面我们用panuon开发一个高仿VS2019启动界面,最终成品如下:
2.1. 设置窗体尺寸和title
新建WPF工程,按第1节配置panuon环境,然后在pu:WindowX继续添加属性
Title="Visual Studio (SIM)"
Height="630"
Width="1058"
MinHeight="630"
MinWidth="1058"
Background="#252526"
BorderBrush="#3E3E45"
BorderThickness="1"
Foreground="#F1F1F1"
2.2. 添加静态资源
2.2.1. 什么是静态资源
资源可以分为静态资源或动态资源进行引用。
分别是通过使用 StaticResource 标记扩展或 DynamicResource 标记扩展完成的。
StaticResource的用法:
通过替换已定义资源的值(x:Key)来为 XAML 属性提供值。
这里添加静态资源就是可以对单个控件的样式单独控制,定制化。为后面的控件样式所用。
<pu:WindowX.Resources><Style x:Key="SearchComboBoxStyle"TargetType="ComboBox"BasedOn="{StaticResource {x:Type ComboBox}}"><Setter Property="pu:ComboBoxHelper.HoverBorderBrush"Value="#007ACC" /><Setter Property="pu:ComboBoxHelper.FocusedBorderBrush"Value="#007ACC" /><Setter Property="Height"Value="35" /><Setter Property="Width"Value="320" /><Setter Property="Background"Value="#333337" /><Setter Property="BorderBrush"Value="#3F3F46" /><Setter Property="Foreground"Value="#F1F1F1" /></Style><Style x:Key="CardButtonStyle"TargetType="Button"BasedOn="{StaticResource {x:Type Button}}"><Setter Property="pu:IconHelper.FontFamily"Value="{StaticResource PanuonIconFont}" /><Setter Property="pu:IconHelper.FontSize"Value="30" /><Setter Property="pu:IconHelper.VerticalAlignment"Value="Top" /><Setter Property="pu:IconHelper.Margin"Value="7,2,17,0" /><Setter Property="pu:ButtonHelper.HoverBackground"Value="#3F3F40" /><Setter Property="pu:ButtonHelper.ClickBackground"Value="{x:Null}" /><Setter Property="Foreground"Value="#F1F1F1" /><Setter Property="Background"Value="#333337" /><Setter Property="Padding"Value="10,7,10,10" /><Setter Property="Height"Value="75" /><Setter Property="VerticalContentAlignment"Value="Stretch" /><Setter Property="HorizontalContentAlignment"Value="Stretch" /></Style><Style x:Key="LinkButtonStyle"TargetType="Button"BasedOn="{StaticResource {x:Type Button}}"><Setter Property="pu:IconHelper.FontFamily"Value="{StaticResource PanuonIconFont}" /><Setter Property="pu:ButtonHelper.HoverBackground"Value="{x:Null}" /><Setter Property="pu:ButtonHelper.ClickBackground"Value="{x:Null}" /><Setter Property="Foreground"Value="#0097FB" /><Setter Property="Background"Value="{x:Null}" /><Setter Property="Cursor"Value="Hand" /><Setter Property="VerticalContentAlignment"Value="Stretch" /><Setter Property="HorizontalContentAlignment"Value="Stretch" /><Style.Triggers><Trigger Property="IsMouseOver"Value="True"><Setter Property="ContentTemplate"><Setter.Value><DataTemplate><TextBlock Text="{Binding}" TextDecorations="Underline"/></DataTemplate></Setter.Value></Setter></Trigger></Style.Triggers></Style><Style x:Key="ProjectListBoxStyle"TargetType="ListBox"BasedOn="{StaticResource {x:Type ListBox}}"><Setter Property="pu:IconHelper.FontFamily"Value="{StaticResource PanuonIconFont}" /><Setter Property="pu:IconHelper.Width"Value="25" /><Setter Property="pu:IconHelper.Height"Value="25" /><Setter Property="pu:IconHelper.VerticalAlignment"Value="Top" /><Setter Property="pu:IconHelper.Margin"Value="0,-15,7,0" /><Setter Property="pu:ListBoxHelper.ItemsHeight"Value="65" /><Setter Property="pu:ListBoxHelper.ItemsPadding"Value="10,0,10,0" /><Setter Property="pu:ListBoxHelper.ItemsHoverBackground"Value="#3F3F40" /><Setter Property="pu:ListBoxHelper.ItemsSelectedBackground"Value="{x:Null}" /><Setter Property="Foreground"Value="#F1F1F1" /><Setter Property="Background"Value="Transparent" /><Setter Property="BorderThickness"Value="0" /><Setter Property="VerticalContentAlignment"Value="Center" /><Setter Property="HorizontalContentAlignment"Value="Stretch" /></Style></pu:WindowX.Resources>
2.3. 主Grid
2.3.1. 盒子模型
主Grid里面的布局需要手写,手写需要有一定布局的基础。如果不是很清楚需要先了解下盒子模型。
盒子模型最开始是应用于网页布局,将页面中所有元素都看作是一个盒子,盒子都包含以下几个属性:
width 宽度
height 高度
border 边框——围绕在内边距和内容外的边框
padding 内边距——清除内容周围的区域,内边距是透明的
margin 外边距——清除边框外的区域,外边距是透明的
content 内容——盒子的内容,显示文本和图像
2.3.2. 嵌套布局
用xaml写布局,当层级嵌套比较深,比较复杂的时候自己都会很晕,这里有个小技巧我经常用,就是给背景/边框标红,这样能直观看到当前的嵌套到哪里了。等找到自己的定位后,在把红色标记去掉。
<Grid Margin="55,0,65,35" Background="Red">
完整的Grid布局代码:
<Grid Margin="55,0,65,35"><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition /></Grid.RowDefinitions><TextBlock Text="Visual Studio 2019 (SIM)"FontSize="33"/><Grid Grid.Row="1"><Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition Width="30"/><ColumnDefinition Width="0.6*" /></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition /></Grid.RowDefinitions><TextBlock Margin="0,30,0,0"Text="Open recent"FontSize="20" /><Grid Grid.Row="1"><Grid.RowDefinitions><RowDefinition Height="Auto" /><RowDefinition /></Grid.RowDefinitions><ComboBox Margin="0,15,0,0"HorizontalAlignment="Left"IsEditable="True"Style="{StaticResource SearchComboBoxStyle}"pu:ComboBoxHelper.Watermark="Search recent" /><ListBox Grid.Row="1"Margin="0,15,0,0"Style="{StaticResource ProjectListBoxStyle}"><ListBoxItem pu:ListBoxItemHelper.Icon="/Samples;component/Resources/WebForms.png"><Grid><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><TextBlock FontSize="14"FontWeight="Bold"Text="ProjectA.sln" /><TextBlock VerticalAlignment="Center"HorizontalAlignment="Right"Foreground="#C6C8D2"Text="2021/4/12 12:00" /><TextBlock Grid.Row="1"Margin="0,8,0,0"Text="D:\ProjectA"TextTrimming="CharacterEllipsis"Foreground="#C6C8D2" /></Grid></ListBoxItem><ListBoxItem pu:ListBoxItemHelper.Icon="/Samples;component/Resources/WebForms.png"><Grid><Grid.RowDefinitions><RowDefinition Height="Auto" /><RowDefinition Height="Auto" /></Grid.RowDefinitions><TextBlock FontSize="14"FontWeight="Bold"Text="ProjectB.sln" /><TextBlock VerticalAlignment="Center"HorizontalAlignment="Right"Foreground="#C6C8D2"Text="2021/4/12 12:00" /><TextBlock Grid.Row="1"Margin="0,8,0,0"Text="D:\ProjectB"TextTrimming="CharacterEllipsis"Foreground="#C6C8D2" /></Grid></ListBoxItem></ListBox></Grid><TextBlock Grid.Column="2"Margin="0,30,0,0"Text="Get started"FontSize="20" /><StackPanel Grid.Column="2"Grid.Row="1"Margin="0,15,0,0"><Button Style="{StaticResource CardButtonStyle}"pu:ButtonHelper.Icon=""><StackPanel><TextBlock FontSize="18"Text="Connect to a codespace"/><TextBlock Margin="0,5,0,0"Text="Create and manage cloud-powered development environments"TextWrapping="Wrap"Foreground="#C6C8D2"/></StackPanel></Button><Button Margin="0,5,0,0"Style="{StaticResource CardButtonStyle}"pu:ButtonHelper.Icon=""><StackPanel><TextBlock FontSize="18"Text="Clone a repository" /><TextBlock Margin="0,5,0,0"Text="Get code from an online repository like GitHub or Azure DevOps"TextWrapping="Wrap"Foreground="#C6C8D2" /></StackPanel></Button><Button Margin="0,5,0,0"Style="{StaticResource CardButtonStyle}"pu:ButtonHelper.Icon=""><StackPanel><TextBlock FontSize="18"Text="Open a project or solution" /><TextBlock Margin="0,5,0,0"Text="Open a local Visual Studio project or .sln file"TextWrapping="Wrap"Foreground="#C6C8D2" /></StackPanel></Button><Button Margin="0,5,0,0"Style="{StaticResource CardButtonStyle}"pu:ButtonHelper.Icon=""><StackPanel><TextBlock FontSize="18"Text="Open a local folder" /><TextBlock Margin="0,5,0,0"Text="Navigate and edit code within any folder"TextWrapping="Wrap"Foreground="#C6C8D2" /></StackPanel></Button><Button Margin="0,5,0,0"Style="{StaticResource CardButtonStyle}"pu:ButtonHelper.Icon=""><StackPanel><TextBlock FontSize="18"Text="Create a new project" /><TextBlock Margin="0,5,0,0"Text="Choose a project template with code scaffolding to get started"TextWrapping="Wrap"Foreground="#C6C8D2" /></StackPanel></Button><StackPanel Margin="0,10,0,0"HorizontalAlignment="Center"Orientation="Horizontal"><Button Style="{StaticResource LinkButtonStyle}"Content="Continue without code" /><TextBlock Text=""VerticalAlignment="Center"Foreground="#0097FB"FontFamily="{StaticResource PanuonIconFont}"/></StackPanel></StackPanel></Grid>
</Grid>
3. 总结
Panuon.WPF.UI
是一个适用于定制个性化UI界面的组件库。它能帮助你快速完成样式和控件的UI设计,而不必深入了解WPF的 ControlTemplate
、 Storyboard
等知识。
例如,在原生WPF中下,如果你想要修改 Button
按钮 控件的悬浮背景色,你需要修改按钮的 Style
属性,并编写 Trigger
和 Storyboard
来实现悬浮渐变效果。如果你想要更复杂的效果,你可能还需要编写内部的ControlTemplate
模板。但现在, Panuon.WPF.UI
为你提供了一个更简单的方式。你只需要在 Button
按钮 控件上添加一条 pu:ButtonHelper.HoverBackground="#FF0000"
属性,即可实现背景色悬浮渐变到红色的效果。Panuon.WPF.UI
为每一种控件都提供了大量的属性,使你能够方便地修改WPF中没有直接提供,但在UI设计中非常常用的效果,这有助于你快速地完成UI设计(尤其是在你有设计图的情况下)。
相关文章:

开始使用Panuon开源界面库环境配置并手写VS2019高仿界面
1. Panuon环境配置 1.1. 通过Nuget 安装 Panuon.WPF.UI1.2. xaml引用命名空间1.3. using Panuon.WPF.UI; 2. VS2019 view 2.1. 设置窗体尺寸和title2.2. 添加静态资源 2.2.1. 什么是静态资源 2.3. 主Grid 2.3.1. 盒子模型2.3.2. 嵌套布局 3. 总结 1. Panuon环境配置 1.1. 通…...

新垂直电商的社交传播策略与AI智能名片2+1链动模式S2B2C商城小程序的应用探索
摘要:随着互联网技术的不断进步和电商行业的快速发展,传统电商模式已难以满足消费者日益增长的个性化和多元化需求。新垂直电商在此背景下应运而生,通过精准定位、用户细分以及深度社交传播策略,实现了用户群体的快速裂变与高效营…...

WPS计算机二级•表格函数计算
听说这里是目录哦 函数基础知识 相对绝对混合引用🌪️相对引用绝对引用混合引用 常用求和函数 SUM函数🌦️语法说明 函数快速求 平均数最值⚡平均数最值 实用统计函数 实现高效统计🌀COUNTCOUNTIF 实用文本函数 高效整理数据🌈RIG…...
ESP32S3官方例程如何使用
一、WIFI 找到app_wifi.c文件 wifi_config_t wifi_config; 把上面代码修改为下面代码 wifi_config_t wifi_config { .sta {.ssid DEFAULT_ESP_WIFI_SSID, //WIFI的SSID.password DEFAULT_ESP_WIFI_PASS, //WIFI密码.threshold.authmode WIFI_AUTH_WPA…...
新版 MacOS 无法从 /usr/local/lib 加载动态链接库的解决办法
自己编写的动态链接库在Unix规范下一般位于/usr/local/lib,在2023年及之前的MacOS版本中,直接将动态库安装到该位置即可在程序运行时加载,可是升级MacOS版本后,ld就报错。 错误现象 运行程序,报错 dyld[6376]: Libra…...
【Varnish】:解决 Varnish 7.6 CDN 静态资源缓存失效问题
项目场景: 在一个使用Varnish作为反向代理的Web应用中,我们依赖CDN(内容分发网络)来缓存静态资源(如图片、CSS、JavaScript文件等),以提高全球用户的访问速度并减轻源站服务器的负载。然而&…...

【记录】篡改猴插件下载网页m3u8视频
1.打开浏览器【管理扩展】页面(edge://extensions/),打开开发人员模式 2.Edge浏览器添加篡改猴插件 3.下载需要的脚本 可以从篡改猴首页找下载网站 https://www.tampermonkey.net/scripts.php?localezh_CN 4.安装成功重启浏览器&#x…...
PID控制器 (Proportional-Integral-Derivative Controller) 算法详解及案例分析
PID控制器 (Proportional-Integral-Derivative Controller) 算法详解及案例分析 目录 PID控制器 (Proportional-Integral-Derivative Controller) 算法详解及案例分析1. 引言2. PID控制器的基本概念2.1 PID控制器的定义2.2 PID控制器的核心思想2.3 PID控制器的应用领域 3. PID控…...

【Java设计模式-5】装饰模式:给咖啡加点“佐料”
今天咱们要探索一下Java世界里的装饰模式(Decorator Pattern)。为了让这个过程更加生动易懂,咱们就以大家都熟悉的咖啡饮品来举例吧,想象一下,你就是那个咖啡大师,要给顾客调制出各种独特口味的咖啡哦&…...
C++ using(八股总结)
using作用: 类型别名using声明using指示 类型别名 using 可以用来创建类型别名,替代传统的 typedef。这在定义复杂类型时尤其有用,例如模板类型。 // 使用 typedef 创建类型别名 typedef long long ll;// 使用 using 创建类型别名 using …...

《分布式光纤传感:架设于桥梁监测领域的 “智慧光网” 》
桥梁作为交通基础设施的重要组成部分,其结构健康状况直接关系到交通运输的安全和畅通。随着桥梁建设规模的不断扩大和服役年限的增长,桥梁结构的安全隐患日益凸显,传统的监测方法已难以满足对桥梁结构健康实时、全面、准确监测的需求。分布式…...

C++(5)
1.运算符重载 头文件 #ifndef MYSTRING_H #define MYSTRING_H#include <iostream> #include <cstring>using namespace std;class myString { private:char *str;//C风格字符串int size0; public:std::string s_str;//转换构造函数myString(const std::string &a…...

【进程与线程】程序和进程在内存中的表现
在计算机系统中,程序和进程是两个密切相关但又有本质区别的概念,尤其在内存中的表现上有显著不同: 在这张图中可以直观地看出程序和进程在内存中的结构区别。 基本定义 程序 程序 是一个 静态实体,表示一组写好的指令和数据的…...

个人主页搭建全流程(Nginx部署+SSL配置+DCDN加速)
前言 最近开始准备秋招,打算做一个个人主页,以便在秋招市场上更有竞争力。 目前,现有的一些搭建主页的博文教程存在以下一些问题: 使用Github Page进行部署,这在国内访问容易受阻使用宝塔面板等框架,功能…...
语音合成的预训练模型
语音合成的预训练模型 与 ASR(语音识别)和音频分类任务相比,语音合成的预训练模型检查点明显较少。在 Hugging Hub 上,可以找到近 300 个适合的检查点。 在这些预训练模型中,重点关注两种在 Huggingface Transformers 库中开箱即用的架构——SpeechT5 和 Massive Multili…...

前端组件开发:组件开发 / 定义配置 / 配置驱动开发 / 爬虫配置 / 组件V2.0 / form表单 / table表单
一、最早的灵感 最早的灵感来自sprider / 网络爬虫 / 爬虫配置,在爬虫爬取网站文章时候,会输入给爬虫一个配置文件,里边的内容是一个json对象。里边包含了所有想要抓取的页面的信息。爬虫通过这个配置就可以抓取目标网站的数据。其实本文要引…...

Swagger生成Api文档的增强解决方案--knife4j
方法一: 使用步骤 1.导入 knife4j 的maven坐标 在pom.xml中添加依赖 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.5.0</ver…...

Node.js - HTTP
1. HTTP请求 HTTP(Hypertext Transfer Protocol,超文本传输协议)是客户端和服务器之间通信的基础协议。HTTP 请求是由客户端(通常是浏览器、手机应用或其他网络工具)发送给服务器的消息,用来请求资源或执行…...
LangChain学习笔记2 Prompt 模板
安装 langchain 库 pip install langchain1、概念:提示和提示工程 在大语言模型(LLMs)时代,通过简单地更改提示中的指令,同一个模型可以执行多种任务。这一特性让 LLMs 在各类应用场景中都显得非常灵活和强大。然而&…...
如何在gitlab cicd中实现每月10号上午执行
在 GitLab CI/CD 中,可以通过设置定时触发器(Schedules)和脚本中的时间判断逻辑结合,确保任务只在每月 10 号的上午运行。 以下是实现的步骤: 1. 设置定时触发器 GitLab 提供了 Schedules 功能,可以指定每…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...