1. 程式人生 > >WPF 文本框設置了陰影效果後,因左右的transform變化引發的拉伸渲染問題

WPF 文本框設置了陰影效果後,因左右的transform變化引發的拉伸渲染問題

time 通過 test onu 方案 des this 如果 splay

原文:WPF 文本框設置了陰影效果後,因左右的transform變化引發的拉伸渲染問題

背景

最近遇到一個動畫執行時,文本位置變化的問題。如下圖:

技術分享圖片

如果你仔細看的話,當星星變小時,文本往下降了幾個像素。

貌似有點莫名其妙,因為控件之間並不在同一個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>
View Code

陰影效果

再嘗試將陰影效果刪除,也不會有影響

技術分享圖片測試通過

重現步驟

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

解決方案(只是規避)

按照如上重現步驟,有三個條件才會出現此問題。

1.設置了陰影效果 2.顯示區域有寬高變更 3.字體類型/字體大小是一個影響幅度因素(影響較小的字體類型與字體大小組合,例如:微軟雅黑UI+字體大小60)

針對這些條件,我們給出規避的解決方案

規避措施1:

不設置陰影效果

技術分享圖片測試通過

規避措施2:

將高度變換的區域移動一點位置,不在帶陰影的控件顯示區域內。

技術分享圖片測試通過

註:至於如上測試步驟中左右結構的多個影響因素

對於帶陰影有控件,如倆側控件同時有高度變化,引發的Y軸位置變化問題,暫時無規避方案。。。

規避措施3

設置一個字體類型+字體大小的最小影響組合,例如FontFamily="Microsoft YaHei UI",FontSize=60;

如果需要加粗,可以通過設置FontWeight加粗:

技術分享圖片 影響很小,不用放大鏡500%查看的話,看不到影響,可以忽略。

註:如上規避措施只是臨時解決方案,如小夥伴們有其它方案或者發現其它根本原因,可以聯系我~謝謝

WPF 文本框設置了陰影效果後,因左右的transform變化引發的拉伸渲染問題