开始使用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="&#xe941;">
                <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="&#xe94d;">
                <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="&#xe951;">
                <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="&#xe956;">
                <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="&#xe960;">
                <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="&#xe90e;"
                       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设计(尤其是在你有设计图的情况下)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Git] 深入理解 Git 的客户端与服务器角色

Git 的一个核心设计理念是 分布式&#xff0c;每个 Git 仓库都可以既是 客户端&#xff0c;也可以是 服务器。为了更好地理解这一特性&#xff0c;我们通过一个实际的 GitHub 远程仓库和本地仓库的场景来详细说明 Git 如何在客户端和服务器之间协作&#xff0c;如何独立地进行版…

基于考研概率论知识解读 Transformer:为何自注意力机制要除以根号 dk

Transformer自注意力机制中除以 d k \sqrt{d_k} dk​ ​深度剖析 【 Transformer 系列&#xff0c;故事从 d k \sqrt{d_k} dk​ ​说起】 LLM这么火&#xff0c;Transformer厥功甚伟&#xff0c;某天心血来潮~&#xff0c;再去看看&#xff01; 它长这个样子&#xff1a; 深入…

使用 selenium-webdriver 开发 Web 自动 UI 测试程序

优缺点 优点 有时候有可能一个改动导致其他的地方的功能失去效果&#xff0c;这样使用 Web 自动 UI 测试程序可以快速的检查并定位问题&#xff0c;节省大量的人工验证时间 缺点 增加了维护成本&#xff0c;如果功能更新过快或者技术更新过快&#xff0c;维护成本也会随之提高…

【Redis】初识分布式系统

目录 单机架构 分布式系统 应用数据分离架构 应用服务集群架构 读写分离/主从分离架构 冷热分离架构 垂直分库 微服务架构 分布式名词概念 本篇博文&#xff0c;将根据分布式系统的演进一步一步介绍每一种架构的形式&#xff0c;最后为大家总结了一些分布式中常用的…

微服务之松耦合

参考&#xff1a;https://microservices.io/post/architecture/2023/03/28/microservice-architecture-essentials-loose-coupling.html There’s actually two different types of coupling: runtime coupling - influences availability design-time coupling - influences…

pytest+request+yaml+allure搭建低编码调试门槛的接口自动化框架

接口自动化非常简单&#xff0c;大致分为以下几步&#xff1a; 准备入参调用接口拿到2中response&#xff0c;继续组装入参&#xff0c;调用下一个接口重复步骤3校验结果是否符合预期 一个优秀接口自动化框架的特点&#xff1a; 【编码门槛低】&#xff0c;又【能让新手学到…

基于Springboot + vue实现的文档管理系统

&#x1f942;(❁◡❁)您的点赞&#x1f44d;➕评论&#x1f4dd;➕收藏⭐是作者创作的最大动力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;&#x1f525;&…

Pycharm连接远程解释器

这里写目录标题 0 前言1 给项目添加解释器2 通过SSH连接3 找到远程服务器的torch环境所对应的python路径&#xff0c;并设置同步映射&#xff08;1&#xff09;配置服务器的系统环境&#xff08;2&#xff09;配置服务器的conda环境 4 进入到程序入口&#xff08;main.py&#…

初学stm32 --- II2C_AT24C02,向EEPROM中读写数据

目录 IIC总线协议介绍 IIC总线结构图 IIC协议时序 1. ACK&#xff08;Acknowledge&#xff09; 2. NACK&#xff08;Not Acknowledge&#xff09; IO口模拟II2C协议 发送起始信号&#xff1a; 发送停止信号&#xff1a; 检测应答信号&#xff1a; 发送应答信号&#x…

Excel 技巧07 - 如何计算到两个日期之间的工作日数?(★)如何排除节假日计算两个日期之间的工作日数?

本文讲了如何在Excel中计算两个日期之间的工作日数&#xff0c;以及如何排除节假日计算两个日期之间的工作日数。 1&#xff0c;如何计算到两个日期之间的工作日数&#xff1f; 其实就是利用 NETWORKDAYS.INTL 函数 - weekend: 1 - 星期六&#xff0c;星期日 2&#xff0c;如…

保姆级图文详解:Linux和Docker常用终端命令

文章目录 前言1、Docker 常用命令1.1、镜像管理1.2、容器管理1.3、网络管理1.4、数据卷管理1.5、监控和性能管理 2、Linux 常用命令分类2.1、文件和目录管理2.2、用户管理2.3、系统监控和性能2.4、软件包管理2.5、网络管理 前言 亲爱的家人们&#xff0c;技术图文创作很不容易…

从玩具到工业控制--51单片机的跨界传奇【2】

咱们在上一篇博客里面讲解了什么是单片机《单片机入门》&#xff0c;让大家对单片机有了初步的了解。我们今天继续讲解一些有关单片机的知识&#xff0c;顺便也讲解一下我们单片机用到的C语言知识。如果你对C语言还不太了解的话&#xff0c;可以看看博主的C语言专栏哟&#xff…

智能物流升级利器——SAIL-RK3576核心板AI边缘计算网关设计方案(一)

近年来&#xff0c;随着物流行业智能化和自动化水平不断提升&#xff0c;数据的实时处理与智能决策成为推动物流运输、仓储管理和配送优化的重要手段。传统的集中式云平台虽然具备强大计算能力&#xff0c;但高延迟和带宽限制往往制约了物流现场的即时响应。为此&#xff0c;我…

HTML拖拽功能(纯html5+JS实现)

1、HTML拖拽--单元行拖动 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><…

Jaeger UI使用、采集应用API排除特定路径

Jaeger使用 注&#xff1a; Jaeger服务端版本为&#xff1a;jaegertracing/all-in-one-1.6.0 OpenTracing版本为&#xff1a;0.33.0&#xff0c;最后一个版本&#xff0c;停留在May 06, 2019。最好升级到OpenTelemetry。 Jaeger客户端版本为&#xff1a;jaeger-client-1.3.2。…

【MySQL】简单解析一条SQL查询语句的执行过程

1. MySQL 的逻辑架构图 MySQL 架构主要分为 Server 层和存储引擎层。Server 层集成了连接器、查询缓存、分析器、优化器和执行器等核心组件&#xff0c;负责提供诸如日期、时间、数学和加密等内置函数&#xff0c;以及实现存储过程、触发器、视图等跨存储引擎的功能。存储引擎层…

如何将json字符串格式化

文章目录 如何对json字符串进行格式化显示hutool方案的示例和不足使用fastjson的方案 如何对json字符串进行格式化显示 将json字符串内容进行格式化的输出显示。本文介绍 hutool的方案和alibaba 的fastjson方案 hutool方案的示例和不足 引入依赖 <dependency><grou…

复杂 C++ 项目堆栈保留以及 eBPF 性能分析

在构建和维护复杂的 C 项目时&#xff0c;性能优化和内存管理是至关重要的。当我们面对性能瓶颈或内存泄露时&#xff0c;可以使用eBPF&#xff08;Extended Berkeley Packet Filter&#xff09;和 BCC&#xff08;BPF Compiler Collection&#xff09;工具来分析。如我们在Red…

unity学习18:unity里的 Debug.Log相关

目录 1 unity里的 Debug.log相关 2 用Debug.DrawLine 和 Debug.DrawRay画线 2.1 画线 1 unity里的 Debug.log相关 除了常用的 Debug.Log&#xff0c;还有另外2个 Debug.Log("Debug.Log"); Debug.LogWarning("Debug.LogWarning"); Debug.LogErro…

IoTDB 常见问题 QA 第三期

关于 IoTDB 的 Q & A IoTDB Q&A 第三期持续更新&#xff01;我们将定期汇总我们将定期汇总社区讨论频繁的问题&#xff0c;并展开进行详细回答&#xff0c;通过积累常见问题“小百科”&#xff0c;方便大家使用 IoTDB。 Q1&#xff1a;查询最新值 & null 数据相加方…