尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

从零开始编写一个办公软件(二、自适应窗口)

从零开始编写一个办公软件(二、自适应窗口)
📅 发布时间:2026/6/18 20:28:48

桌面开发通常需要面对因为屏幕大小不同产生的视觉过大或过小的问题,基本都会被要求做大小自适应处理。网上一般介绍的是ViewBox,简单方便,但不仅面临性能的问题,部分情况下还会出现UI失真。我这里介绍下更繁琐但实用的方法,虽然开发起来麻烦不少,但运行效果会好很多。
首先建立一个资源字典,把所有和尺寸相关的数值都放进这个字典文件中,举个例子:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=netstandard" xmlns:m="http://schemas.microsoft.com/netfx/2009/xaml/presentation"><!--#region Double--><sys:Double x:Key="D_1d5">1.5</sys:Double><sys:Double x:Key="D_2">2</sys:Double><sys:Double x:Key="D_8">8</sys:Double><sys:Double x:Key="D_30">30</sys:Double><sys:Double x:Key="D_45">45</sys:Double><sys:Double x:Key="D_48">48</sys:Double><sys:Double x:Key="D_640">640</sys:Double><sys:Double x:Key="D_960">960</sys:Double><!--#endregion--><!--#region Thickness--><m:Thickness x:Key="T_1d5">1.5</m:Thickness><m:Thickness x:Key="T_2">2</m:Thickness><m:Thickness x:Key="T_7">7</m:Thickness><m:Thickness x:Key="T_0_48_0_0">0 48 0 0</m:Thickness><!--#endregion--><!--#region Geometry--><m:Geometry x:Key="MinimizeButtonGeometry">M0,0 12,0</m:Geometry><m:Geometry x:Key="MaximizeButtonGeometry1">M0,0 12,0 12,10 0,10 z</m:Geometry><m:Geometry x:Key="MaximizeButtonGeometry2">M0,3 0,12 9,12 9,3 z M3,3 3,0 12,0 12,9 9,9</m:Geometry><m:Geometry x:Key="CloseButtonGeometry">M0,0 12,12 M12,0 0,12</m:Geometry><!--#endregion--><!--#region CornerRadius--><m:CornerRadius x:Key="CR_8">8</m:CornerRadius><!--#endregion-->
</ResourceDictionary>

然后是重点,千万不要在xaml里引用这个字典!
考虑到开发过程当中的设计问题,可以这么写:

<Window x:Class="LkWork.WPF.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:LkWork.WPF"mc:Ignorable="d" WindowStartupLocation="CenterScreen"Title="MainWindow" Height="{DynamicResource D_640}" Width="{DynamicResource D_960}"><Window.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><d:ResourceDictionary Source="pack://application:,,,/LkWork.WPF;component/Resources/Styles/WindowSizeStyles.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Window.Resources><Grid></Grid>
</Window>

在ResourceDictionary前面加上d:,既不影响使用,又比较方便开发。

然后开始使用了,打开App.xaml.cs文件,替换代码

using Microsoft.Win32;
using System.Configuration;
using System.Data;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;namespace LkWork.WPF
{/// <summary>/// Interaction logic for App.xaml/// </summary>public partial class App : Application{protected override void OnStartup(StartupEventArgs e){//监听显示设置变化事件SystemEvents.DisplaySettingsChanging += SystemEvents_DisplaySettingsChanging;InitializeAppSize();base.OnStartup(e);}private double WindowScale = 1;private void SystemEvents_DisplaySettingsChanging(object? sender, EventArgs e){InitializeAppSize();}private void InitializeAppSize(){ResourceDictionary resource = new ResourceDictionary() { Source = new Uri("pack://application:,,,/LkWork.WPF;component/Resources/Styles/WindowSizeStyles.xaml", UriKind.Absolute) };var firstKey = resource.Keys.Cast<string>().First();double scale = Math.Max(SystemParameters.PrimaryScreenWidth / 1920, SystemParameters.PrimaryScreenHeight / 1080);if (firstKey is not null){if (Math.Abs(scale - WindowScale) > 0.1) return; //缩放比例没有变化则不处理var old = this.Resources.MergedDictionaries.Where(x => x.Contains(firstKey)).FirstOrDefault();if (old is not null) this.Resources.MergedDictionaries.Remove(old);}//缩放比例有比较明显的变化,需要调整资源中的数值if (Math.Abs(scale - WindowScale) > 0.1){foreach (var key in resource.Keys.Cast<string>()){var value = resource[key];if (value is double d){resource.Remove(key);resource.Add(key, d * scale);}else if (value is Thickness t){resource.Remove(key);resource.Add(key, new Thickness(t.Left * scale, t.Top * scale, t.Right * scale, t.Bottom * scale));}else if (value is CornerRadius c){resource.Remove(key);resource.Add(key, new CornerRadius(c.TopLeft * scale, c.TopRight * scale, c.BottomRight * scale, c.BottomLeft * scale));}else if(value is Geometry g){g = g.Clone();g.Transform = new ScaleTransform(scale, scale, 0, 0);g.Freeze();resource.Remove(key);resource.Add(key, g);}}//窗口大小需要额外调整foreach (Window window in this.Windows){if (!double.IsNaN(window.Width)) window.Width *= scale / WindowScale;if (!double.IsNaN(window.Height)) window.Height *= scale / WindowScale;}}this.Resources.MergedDictionaries.Add(resource);WindowScale = scale;}}}

运行代码,调整显示缩放查看效果
image
我这里是成功更改大小了的,收工。

相关新闻

  • 代码大全2,阅读1
  • 如果我想在项目发布后,动态更新组件,如何使用模块联邦实现?
  • 静态类型、动态类型、强类型、弱类型

最新新闻

  • 华硕笔记本风扇异常诊断与修复:5分钟解决散热系统失控问题
  • 10分钟搞定ESP32开发环境:Arduino ESP32终极安装指南
  • 不平衡数据处理三层次实战:数据/算法/评估全链路方案
  • 2026年广州展厅设计公司排名:基于性价比与综合服务能力分类 - 信息热点
  • 重庆托福培训哪家强?实地验证搭配免费试听 - 晴光转树
  • ComfyUI_smZNodes:5大核心技术突破实现跨平台AI绘画一致性解决方案

日新闻

  • 2026年不锈钢卷板厂家推荐排行榜:冷轧热轧/304/201不锈钢卷板,高颜值耐腐蚀源头厂家实力精选 - 企业推荐官【官方】
  • FLUX.1-dev FP8模型实战指南:24GB以下显卡高效部署方案
  • 2026佛山长途搬家价目表:跨省跨市搬家费用完整计算指南 - 从来都是英雄出少年

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号