WPF附加依赖属性实现自适应字体大小(根据屏幕分辨率变化)

前言

近来有个需求,软件需要动态适配屏幕分辨率,为了保证整体界面的一致性,字体的大小需要根据不同的屏幕分辨率自适应大小。此篇只为给提供一个处理的方法,直接使用也可以,不过还需要有一些改动。此处只做一个简单版本的记录。

使用方法

  1. 初始化 RelativeSizeAttach.Init(1920,1080)(用于计算屏幕的宽高转换比)
  2. 引入命名空间xmlns:前缀="clr-namespace:命名空间名称;assembly:程序集名称"
  3. 在需要使用自适应附加属性的xaml标签内进行属性值设置。
    例如:前缀:RelativeSizeAttach.FontSize="16";

代码

public class RelativeSizeAttach

{#region 宽高

 

​ public static readonly DependencyProperty WidthProperty
​ = DependencyProperty.RegisterAttached("Width", typeof(double), typeof(RelativeSizeAttach), new FrameworkPropertyMetadata(0.0, WidthPropertyChangedCallback));

 

​ public static void SetWidth(DependencyObject element, double value) => element.SetCurrentValue(WidthProperty, value);

 

​ public static double GetWidth(DependencyObject element) => (double)element.GetValue(WidthProperty);

 

​ private static void WidthPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
​ {
​ if (d is ColumnDefinition column)
​ {
​ column.SetCurrentValue(ColumnDefinition.WidthProperty, new GridLength(WidthRateConverter((double)e.NewValue)));
​ }
​ else if (d is FrameworkElement element)
​ {
​ element.SetCurrentValue(FrameworkElement.WidthProperty, WidthRateConverter((double)e.NewValue));
​ }
​ }


​ public static readonly DependencyProperty HeightProperty
​ = DependencyProperty.RegisterAttached("Height", typeof(double), typeof(RelativeSizeAttach), new FrameworkPropertyMetadata(0.0, HeightPropertyChangedCallback));

​ public static void SetHeight(DependencyObject element, double value) => element.SetCurrentValue(HeightProperty, value);

 

​ public static double GetHeight(DependencyObject element) => (double)element.GetValue(HeightProperty);

 

​ private static void HeightPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
​ {
​ if (d is RowDefinition row)
​ {
​ row.SetCurrentValue(RowDefinition.HeightProperty, new GridLength(HeightRateConverter((double)e.NewValue)));
​ }
​ else if (d is FrameworkElement element)
​ {
​ element.SetCurrentValue(FrameworkElement.HeightProperty, HeightRateConverter((double)e.NewValue));
​ }
​ }

 

​ #endregion#region 字体大小

 

​ public static readonly DependencyProperty FontSizeProperty
​ = DependencyProperty.RegisterAttached("FontSize", typeof(double), typeof(RelativeSizeAttach), new FrameworkPropertyMetadata(0.0, FontSizePropertyChangedCallback));

 

​ public static void SetFontSize(DependencyObject element, double value) => element.SetCurrentValue(FontSizeProperty, value);

 

​ public static double GetFontSize(DependencyObject element) => (double)element.GetValue(FontSizeProperty);

 

​ private static void FontSizePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
​ {
​ if (d is TextBlock txtBlock)
​ {
​ txtBlock.SetCurrentValue(TextBlock.FontSizeProperty, WidthRateConverter((double)e.NewValue));
​ }
​ }
​ #endregion#region 行高

 

​ public static readonly DependencyProperty LineHeightProperty
​ = DependencyProperty.RegisterAttached("LineHeight", typeof(double), typeof(RelativeSizeAttach), new FrameworkPropertyMetadata(0.0, LineHeightPropertyChangedCallback));

 

​ public static void SetLineHeight(DependencyObject element, double value) => element.SetCurrentValue(LineHeightProperty, value);

 

​ public static double GetLineHeight(DependencyObject element) => (double)element.GetValue(LineHeightProperty);

 

​ private static void LineHeightPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
​ {
​ if (d is TextBlock txtBlock)
​ {
​ txtBlock.SetCurrentValue(TextBlock.LineHeightProperty, WidthRateConverter((double)e.NewValue));
​ }
​ }


​ #endregion#region 边距


​ public static readonly DependencyProperty MarginProperty
​ = DependencyProperty.RegisterAttached("Margin", typeof(Thickness), typeof(RelativeSizeAttach), new FrameworkPropertyMetadata(new Thickness(0), MarginPropertyChangedCallback));

​ public static void SetMargin(DependencyObject element, Thickness value) => element.SetCurrentValue(MarginProperty, value);
​ public static Thickness GetMargin(DependencyObject element) => (Thickness)element.GetValue(MarginProperty);

 

​ private static void MarginPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
​ {
​ if (d is FrameworkElement element)
​ {
​ element.SetCurrentValue(FrameworkElement.MarginProperty, ThicknessRateConverter((Thickness)e.NewValue));
​ }
​ }

 

​ public static readonly DependencyProperty PaddingProperty
​ = DependencyProperty.RegisterAttached("Padding", typeof(Thickness), typeof(RelativeSizeAttach), new FrameworkPropertyMetadata(new Thickness(0), PaddingPropertyChangedCallback));

​ public static void SetPadding(DependencyObject element, Thickness value) => element.SetCurrentValue(PaddingProperty, value);
​ public static Thickness GetPadding(DependencyObject element) => (Thickness)element.GetValue(PaddingProperty);


​ private static void PaddingPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
​ {
​ if (d is Border border)
​ {
​ border.SetCurrentValue(Border.PaddingProperty, ThicknessRateConverter((Thickness)e.NewValue));
​ }
​ }

​ #endregion#region 数据处理

​ private static double _widthRate = 1;

​ private static double _heightRate = 1;
​ /// <summary>/// 初始化方法/// </summary>/// <param name="deviceWidth">设备宽度</param>/// <param name="deviceHeight">设备高度</param>/// <param name="designWidth">设计图宽度</param>/// <param name="designHeight">设计图高度</param>

​ public static void Init(double deviceWidth, double deviceHeight, double designWidth = 1024, double designHeight = 768)
​ {
​ _widthRate = deviceWidth / designWidth;

​ _heightRate = deviceHeight / designHeight;
​ }

 

​ private static double WidthRateConverter(double value) => value * _widthRate;

 

​ private static double HeightRateConverter(double value) => value * _heightRate;

 

​ private static Thickness ThicknessRateConverter(Thickness value)
​ {
​ value.Left *= _widthRate;
​ value.Top *= _heightRate;
​ value.Right *= _widthRate;
​ value.Bottom *= _heightRate;
​ return value;
​ }


​ #endregion
}

个人站:https://oldteacup.com/

posted @   November's  阅读(1535)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示