WPF 设置控件阴影后,引发的Y轴位置变化问题

简介: 原文:WPF 设置控件阴影后,引发的Y轴位置变化问题背景 最近遇到一个动画执行时,文本位置变化的问题。如下图: 如果你仔细看的话,当星星变小时,文本往下降了几个像素。 貌似有点莫名其妙,因为控件之间并不在同一个Panel布局控件中,不存在高度限制变化引发此类问题。
原文: WPF 设置控件阴影后,引发的Y轴位置变化问题

背景

最近遇到一个动画执行时,文本位置变化的问题。如下图:

如果你仔细看的话,当星星变小时,文本往下降了几个像素。

貌似有点莫名其妙,因为控件之间并不在同一个Panel布局控件中,不存在高度限制变化引发此类问题。所以有了如下测试

测试场景

1. 首先新建了一个空项目,前面是一个带阴影的文本,后面用一张普通图片循环变更它的高度。尝试了下,还是会移动Y轴的像素

 测试不通过

2. 后面使用用普通的布局控件Grid代替。依然如此

测试不通过

所以此问题不是图片动画造成的。

3. 于是,我再添加个按钮,测试带阴影的非文本控件

测试不通过

只有文本被影响了,按钮不会被影响。是按钮的原因?

4. 那么我们将按钮的边框干掉

 

按钮还是不会被影响。。。

5. 给按钮设置,被影响文本同样的字体系列。

 

按钮也被影响了。。。所以,是字体原因!那么,这种字体类型是什么呢? FontFamily="Microsoft YaHei Bold"

6. 我们回到只有文本的测试模式

 测试不通过

测试通过

所以,我们可以得出是Y轴位置变化,是字体类型微软雅黑造成的了。

7. 除了微软雅黑和微软雅黑加粗,其它字体类型是否会影响呢?

测试不通过

 

 测试通过

通过如上测试,发现只有微软雅黑UI字体类型才不会有影响。并且在步骤6中,测试通的是没有设置字体类型的,没有设置字体类型,其实默认是 Microsoft YaHei UI。

8. 另,我们将高度变换的区域移动下位置,也不会有影响。

测试通过

9. 再尝试将阴影效果删除,也不会有影响

测试通过

重现步骤

1.添加一个文本/按钮控件

2.此显示控件设置阴影(条件一)

3.此显示控件设置字体类型FontFamily(条件二),如下

1     <TextBlock x:Name="TestTextBlock1"  VerticalAlignment="Center" HorizontalAlignment="Center"
2                 Text="微软雅黑加粗" Foreground="White" LineHeight="18" FontSize="60" FontFamily="Microsoft YaHei Bold">
3         <TextBlock.Effect>
4             <DropShadowEffect Color="#000000" BlurRadius="4" ShadowDepth="2" Opacity="0.24"/>
5         </TextBlock.Effect>
6     </TextBlock>

4.在此显示控件的显示区域,变更其它控件的高度(条件三)

完整案例如下:

 1 <Window x:Class="TextBlockShadowEffectForStoryBoardDemo.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:TextBlockShadowEffectForStoryBoardDemo"
 7         mc:Ignorable="d" Title="MainWindow" Height="600" Width="800" Background="LightGray">
 8     <Window.Resources>
 9         <Storyboard x:Key="Storyboard.ChangeHeight" DesiredFrameRate="20">
10             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="StoryControl" Storyboard.TargetProperty="Height" RepeatBehavior="Forever">
11                 <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0" />
12                 <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="15" />
13                 <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="30" />
14                 <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="30" />
15                 <EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="15" />
16                 <EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="0" />
17                 <EasingDoubleKeyFrame KeyTime="0:0:2" Value="0" />
18             </DoubleAnimationUsingKeyFrames>
19         </Storyboard>
20     </Window.Resources>
21     <Grid>
22         <Border VerticalAlignment="Center" BorderBrush="Red" BorderThickness="0 1 0 0"></Border>
23 
24         <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Height="80" Width="60" Margin="0 60 0 0">
25             <Grid x:Name="StoryControl" Background="Red"
26                        Height="30" Width="30" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5"/>
27         </Grid>
28         <TextBlock x:Name="TestTextBlock1"  VerticalAlignment="Center" HorizontalAlignment="Center"
29                 Text="微软雅黑加粗" Foreground="White" LineHeight="18" FontSize="60" FontFamily="Microsoft YaHei Bold">
30             <TextBlock.Effect>
31                 <DropShadowEffect Color="#000000" BlurRadius="4" ShadowDepth="2" Opacity="0.24"/>
32             </TextBlock.Effect>
33         </TextBlock>
34     </Grid>
35 </Window>
 1     /// <summary>
 2     /// MainWindow.xaml 的交互逻辑
 3     /// </summary>
 4     public partial class MainWindow : Window
 5     {
 6         public MainWindow()
 7         {
 8             InitializeComponent();
 9             this.Loaded += MainWindow_Loaded;
10         }
11 
12         private void MainWindow_Loaded(object sender, RoutedEventArgs e)
13         {
14             var storyboard = Resources["Storyboard.ChangeHeight"] as Storyboard;
15             storyboard?.Begin();
16         }
17     }

界面显示:

 

解决方案 

按照如上重现步骤,有三个条件才会出现此问题。

1.设置了非Microsoft YaHei UI系列的字体 2.设置了阴影效果 3.显示区域有宽高变更

针对这些条件,我们给出规避的解决方案

 推荐解决方案(规避措施):

按照如上有问题的场景,我们得出结论,是因为字体类型设置导致的。

所以,我们如果不设置字体类型FontFamily,改其它字体类型为Microsoft YaHei UI/Microsoft YaHei UI Light,

如果需要加粗,可以通过设置FontWeight加粗:

  测试OK

其它解决方案(规避措施):

按照如上测试,将高度变换的区域移动,或者不设置阴影效果,也不会有此文所未Y方向位置变化的问题。

 

注:如上规避措施只是临时解决方案,如小伙伴们有其它方案或者发现其它根本原因,可以联系我~谢谢

目录
相关文章
|
4月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
|
4月前
|
C# 开发者 Windows
一款基于Fluent设计风格、现代化的WPF UI控件库
一款基于Fluent设计风格、现代化的WPF UI控件库
118 1
|
4月前
|
C# Windows
WPF中如何使用HandyCotrol控件库
WPF中如何使用HandyCotrol控件库
212 1
|
4月前
|
C# 前端开发 UED
WPF数据验证实战:内置控件与自定义规则,带你玩转前端数据验证,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据验证是确保输入正确性的关键环节。前端验证能及时发现错误,提升用户体验和程序可靠性。本文对比了几种常用的WPF数据验证方法,并通过示例展示了如何使用内置验证控件(如`TextBox`)及自定义验证规则实现有效验证。内置控件结合`Validation`类可快速实现简单验证;自定义规则则提供了更灵活的复杂逻辑支持。希望本文能帮助开发者更好地进行WPF数据验证。
153 0
|
4月前
|
C# UED 定位技术
WPF控件大全:初学者必读,掌握控件使用技巧,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,控件是实现用户界面交互的关键元素。WPF提供了丰富的控件库,包括基础控件(如`Button`、`TextBox`)、布局控件(如`StackPanel`、`Grid`)、数据绑定控件(如`ListBox`、`DataGrid`)等。本文将介绍这些控件的基本分类及使用技巧,并通过示例代码展示如何在项目中应用。合理选择控件并利用布局控件和数据绑定功能,可以提升用户体验和程序性能。
84 0
|
4月前
|
开发框架 前端开发 JavaScript
WPF应用开发之控件动态内容展示
WPF应用开发之控件动态内容展示
|
4月前
|
开发框架 前端开发 JavaScript
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(3)--自定义用户控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(3)--自定义用户控件
|
4月前
|
前端开发 C#
wpfui:一个开源免费具有现代化设计趋势的WPF控件库
wpfui:一个开源免费具有现代化设计趋势的WPF控件库
166 0
|
4月前
|
开发框架 前端开发 C#
使用WPF开发自定义用户控件,以及实现相关自定义事件的处理
使用WPF开发自定义用户控件,以及实现相关自定义事件的处理
|
4月前
|
开发框架 前端开发 JavaScript
在WPF应用中使用GongSolutions.WPF.DragDrop实现列表集合控件的拖动处理
在WPF应用中使用GongSolutions.WPF.DragDrop实现列表集合控件的拖动处理