背景
最近遇到一個動畫執行時,文本位置變化的問題。如下圖:
如果你仔細看的話,當星星變小時,文本往下降了幾個像素。
貌似有點莫名其妙,因為控件之間並不在同一個Panel布局控件中,不存在高度限制變化引發此類問題。所以有了如下測試
測試場景
字體類型影響
1. 首先新建了一個空項目,前面是一個帶陰影的文本,后面用一張普通圖片循環變更它的高度。嘗試了下,還是會移動Y軸的像素
影響很大
2. 后面使用用普通的布局控件Grid代替。依然如此
影響較大
所以此問題不是圖片動畫造成的。
3. 於是,我再添加個按鈕,測試帶陰影的非文本控件
只有文本被影響了,按鈕不會被影響?
我們使用放大鏡,放大到500%,發現按鈕中的文本,上下位置其實還是會有細微的變化 。
所以,按鈕等控件其實也是會被影響的。只是幅度較小。
5. 給按鈕設置,被影響文本同樣的字體系列。
按鈕也被影響了。。。所以,是字體原因!那么,這種字體類型是什么呢?
當前字體: FontFamily="Microsoft YaHei Bold"。
而上一步操作4中,按鈕的字體類型是默認字體,即為Microsoft YaHei UI。
所以Microsoft YaHei Bold的影響比Microsoft YaHei UI大很多?
6. 我們回到只有文本的測試模式
影響較大
影響較小
所以,我們可以得出是Y軸位置變化,的確與字體類型有關。
變動很大
變動很小,使用放大鏡500%才能看到細微的變化
通過如上測試,發現只有微軟雅黑UI字體類型,影響較小。並且在步驟6中,測試通的是沒有設置字體類型的,沒有設置字體類型,其實默認是 Microsoft YaHei UI。所以字體類型影響相對較小的是Microsoft YaHei UI
字體大小
根據上述的字體類型測試,我們添加倆個文本框,使用Microsoft YaHei UI作為字體類型,設置字體大小分別為30和60。
通過如上對比,發現字體大小30的文本,受到的影響很明顯。字體為60的文本,受到的影響較小。
綜上,得出的結論是,Y軸變化的幅度,與字體類型、字體大小有關。具體的詳細幅度,有待確認~~~
顯示區域影響
單個影響因素
我們將高度變換的區域移動下位置,也不會有影響。
測試通過
多個影響因素
有多個影響因素時,不要設置在左右,否則也有影響。
測試不通過
測試通過
Demo前端代碼:

1 <Grid> 2 <Border VerticalAlignment="Center" BorderBrush="Red" BorderThickness="0 1 0 0"></Border> 3 4 <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Height="80" Width="60" Margin="-460 0 0 0"> 5 <Grid x:Name="StoryControl" Background="Red" 6 Height="30" Width="30" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5"/> 7 </Grid> 8 9 <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Height="80" Width="60" Margin="460 0 0 0"> 10 <Grid x:Name="StoryControl1" Background="Red" 11 Height="30" Width="30" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5"/> 12 </Grid> 13 14 <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> 15 <TextBlock x:Name="TestTextBlock0" VerticalAlignment="Center" HorizontalAlignment="Center" 16 Text="YaHei Bold" Foreground="White" LineHeight="18" FontSize="60" FontFamily="Microsoft YaHei Bold"> 17 <TextBlock.Effect> 18 <DropShadowEffect Color="#000000" BlurRadius="4" ShadowDepth="2" Opacity="0.24"/> 19 </TextBlock.Effect> 20 </TextBlock> 21 </StackPanel> 22 </Grid>
陰影效果
再嘗試將陰影效果刪除,也不會有影響
測試通過
重現步驟
1.添加一個文本/按鈕控件
2.此顯示控件設置陰影(條件一)
3.此顯示控件設置字體類型FontFamily=“Microsoft YaHei Bold”(影響因素,不是條件),如下
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 }
界面顯示:
測試Demo請點擊下載:https://files.cnblogs.com/files/kybs0/TextBlockShadowEffectDemo.zip
解決方案
TextOptions.TextFormattingMode,有兩種設置:
- Ideal —— WPF4之前的模式
- Display —— 新的模式,可以使字體顯示更清晰。
TextOptions.TextFormattingMode="Display",可以提高字體的清晰度。
測試OK
TextOptions.TextFormattingMode是依賴屬性,設置后子元素等都能解決此類問題。