原文: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(条件二),如下

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

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

完整案例如下:

 <Window x:Class="TextBlockShadowEffectForStoryBoardDemo.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:TextBlockShadowEffectForStoryBoardDemo"
mc:Ignorable="d" Title="MainWindow" Height="600" Width="800" Background="LightGray">
<Window.Resources>
<Storyboard x:Key="Storyboard.ChangeHeight" DesiredFrameRate="20">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="StoryControl" Storyboard.TargetProperty="Height" RepeatBehavior="Forever">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="15" />
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="30" />
<EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="30" />
<EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="15" />
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Grid>
<Border VerticalAlignment="Center" BorderBrush="Red" BorderThickness="0 1 0 0"></Border> <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Height="80" Width="60" Margin="0 60 0 0">
<Grid x:Name="StoryControl" Background="Red"
Height="30" Width="30" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5"/>
</Grid>
<TextBlock x:Name="TestTextBlock1" VerticalAlignment="Center" HorizontalAlignment="Center"
Text="微软雅黑加粗" Foreground="White" LineHeight="18" FontSize="60" FontFamily="Microsoft YaHei Bold">
<TextBlock.Effect>
<DropShadowEffect Color="#000000" BlurRadius="4" ShadowDepth="2" Opacity="0.24"/>
</TextBlock.Effect>
</TextBlock>
</Grid>
</Window>
     /// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
} private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var storyboard = Resources["Storyboard.ChangeHeight"] as Storyboard;
storyboard?.Begin();
}
}

界面显示:

解决方案

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

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

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

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

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

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

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

  测试OK

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

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

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

WPF 设置控件阴影后,引发的Y轴位置变化问题的更多相关文章

  1. WPF设置控件获取键盘焦点时的样式FocusVisualStyle

    控件获取焦点除了用鼠标外,可以通过键盘来获取,比如Tab键或者方向键等,需要设置控件获取键盘焦点时的样式,可以通过设置FrameworkElemnt.FocusVisualStyle属性, 因为几乎所 ...

  2. WPF设置控件获得焦点FocusManager

      简单用法如下: 在父类容器中通过附加属性FocusManager.FocusedElement来绑定需要强制获得焦点的控件,用法如下: <Grid FocusManager.FocusedE ...

  3. WPF设置控件获得焦点

    1.这个比较有效 this.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)(() => { Keyboard.Foc ...

  4. WPF中通过代码设置控件的坐标

    用WPF做贪吃蛇小游戏时,发现了一个问题: 贪吃蛇的移动,我是通过不断刷新Rectangle来实现(贪吃蛇的身体由一组Rectangle组成),因此需要不断调整Rectangle的坐标,但是WPF中没 ...

  5. WPF:DataTemplateSelector设置控件不同的样式

    原文 WPF:DataTemplateSelector设置控件不同的样式 最近想实现这么个东西,一个ListBox, 里面的ListBoxItem可能是文本框.下拉框.日期选择控件等等. 很自然的想到 ...

  6. WPF 后台C#设置控件背景图片

    原文:WPF 后台C#设置控件背景图片 以前的程序中有做过,当时只是记得uri很长一大段就没怎么记.今天有人问了也就写下来.   这是一个Button,设置了Background后的效果. 前台的设置 ...

  7. WPF ListView控件设置奇偶行背景色交替变换以及ListViewItem鼠标悬停动画

    原文:WPF ListView控件设置奇偶行背景色交替变换以及ListViewItem鼠标悬停动画 利用WPF的ListView控件实现类似于Winform中DataGrid行背景色交替变换的效果,同 ...

  8. WPF 程序如何跨窗口/跨进程设置控件焦点

    原文:WPF 程序如何跨窗口/跨进程设置控件焦点 WPF 程序提供了 Focus 方法和 TraversalRequest 来在 WPF 焦点范围内转移焦点.但如果 WPF 窗口中嵌入了其他框架的 U ...

  9. WPF常用控件应用demo

    WPF常用控件应用demo 一.Demo 1.Demo截图如下: 2.demo实现过程 总体布局:因放大缩小窗体,控件很根据空间是否足够改变布局,故用WrapPanel布局. <ScrollVi ...

随机推荐

  1. Nginx+ 多个Memcached+ 多个Tomcat集群配置来实现 sticky Session

    假如有 大于2 台的Tomcat servers,如何实现sticky session特点的高可靠web 服务? 方案设计: 前端使用nginx(最好是淘宝的 tengine)作为we 流量分发器,向 ...

  2. 使用JQuery将前端form表单数据转换为JSON字符串传递到后台处理

    一般地,我们在处理表单(form表单哦)数据时,传输对象或字符串到后台,Spring MVC或SpringBoot的Controller接收时使用一个对象作为参数就可以被正常接收并封装到对象中.这种方 ...

  3. 黑马程序猿-assign、retain、release、nonatomic、atomic、strong、weak

    都是用于修饰@property声明的变量 assign:用于非oc对象类型,表示直接赋值(默认值) retain:用于mrc中,用于类属性中有oc对象的情况,表示先推断赋值的对象是否和实例对象变量的值 ...

  4. [Vue] Preload Data using Promises with Vue.js and Nuxt.js

    Nuxt.js allows you to return a Promise from your data function so that you can asynchronously resolv ...

  5. RMAN之一:快速入门 分类: H2_ORACLE 2014-02-17 16:11 689人阅读 评论(0) 收藏

    1.数据导出基础 (1)创建datapump导出文件的目录对象并为相应用户授予权限. 出于安全考虑,不允许oracle用户直接在OS上进行文件的操作,而应通过directory对象指定. SQL> ...

  6. python implementation for Qt's QDataStream(看一下QDataStream的结构)

    #!/usr/bin/env python # -*- coding: utf- -*- from __future__ import print_function from __future__ i ...

  7. [Angular] Create custom validators for formControl and formGroup

    Creating custom validators is easy, just create a class inject AbstractControl. Here is the form we ...

  8. ArcEngine创建IElement简单例子

    转自IT-GIS终结者原文ArcEngine创建IElement简单例子 代码下载地址:http://files.cnblogs.com/ogis/MapControlApplication2.rar ...

  9. Curator简介

    Curator简介 Curator是一个博物馆或者其它集合的监管者或者管理者,Curator有以下几个组件组成: Recipes: 实现了通用ZooKeeper的recipes, 该组件是在Frame ...

  10. 学习鸟哥的Linux私房菜笔记(6)——过滤器、输入输出及管道

    一.过滤器 Linux中的应用工具分为三种: 交互工具 过滤器 编辑器 能够接受数据,过滤再输出的工具,称之为过滤器 对过滤器和进程,存在着输入源与输出对象 二.输入.输出.重定向 输入:过滤器的数据 ...