我正在嘗試基于控制元件在WinUI 3TextBlock
中創建一個自定義控制元件,該控制元件必須使用隨機字母滾動效果(逐個字母)顯示包含的文本,直到顯示全文。比如說機場出發廣告牌……
為了更好地理解所需的效果,這是一個使用 Adob??e After Effects 制作所需結果的視頻。
如何在 C# 代碼中實作(最接近的)效果?
uj5u.com熱心網友回復:
在我的解決方案中,影片是通過設定 Text DependencyProperty 來觸發的。如果在當前影片期間重寫了 Text 屬性,則可以輕松地重新啟動效果。但是你也可以通過一些公共方法來觸發它。但請記住,TextBlock 控制元件可能會因大量文本和快速文本更改而變慢。如果您遇到性能問題,您應該為 Win2D CanvasControl 重寫它。
LetterRevealTextBlock.xaml:
<UserControl
x:Class="Test.WinUI3.LetterRevealTextBlock"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Test.WinUI3"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<TextBlock x:Name="LRTB" FontFamily="Consolas"/>
</UserControl>
LetterRevealTextBlock.xaml.cs:
namespace Test.WinUI3;
public sealed partial class LetterRevealTextBlock : UserControl
{
private static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(LetterRevealTextBlock), new PropertyMetadata("", (d, e) => ((LetterRevealTextBlock)d).TextChanged(d, e)));
public string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); }
private static readonly DependencyProperty ScrollIntervalProperty = DependencyProperty.Register(
"ScrollInterval", typeof(int), typeof(LetterRevealTextBlock), new PropertyMetadata(40, (d, e) => ((LetterRevealTextBlock)d).ScrollIntervalChanged(d, e)));
public int ScrollInterval { get => (int)GetValue(ScrollIntervalProperty); set => SetValue(ScrollIntervalProperty, value); }
private static readonly DependencyProperty RevealIntervalProperty = DependencyProperty.Register(
"RevealInterval", typeof(int), typeof(LetterRevealTextBlock), new PropertyMetadata(200, (d, e) => ((LetterRevealTextBlock)d).RevealIntervalChanged(d, e)));
public int RevealInterval { get => (int)GetValue(RevealIntervalProperty); set => SetValue(RevealIntervalProperty, value); }
const string Chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789";
private Random Random = new Random();
private char[] TextArray {get; set; }
private int CurrentChar = 0;
private DispatcherTimer RevealTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(200) };
private DispatcherTimer ScrollTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(40) };
private void ScrollIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ScrollTimer.Interval = TimeSpan.FromMilliseconds((int)e.NewValue);
}
private void RevealIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
RevealTimer.Interval = TimeSpan.FromMilliseconds((int)e.NewValue);
}
private void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TextArray = (e.NewValue as string).ToCharArray();
CurrentChar = 0;
ScrollTimer.Start();
RevealTimer.Start();
}
private void ScrollTimer_Tick(object sender, object e)
{
for (int i = 0; i < Text.Length; i )
{
if (i <= CurrentChar)
{
TextArray[i] = Text[i];
}
else
{
TextArray[i] = Text[i] == ' ' ? ' ' : Chars[Random.Next(Chars.Length - 1)];
}
}
LRTB.Text = new string(TextArray);
if (CurrentChar >= Text.Length - 1)
{
CurrentChar = 0;
ScrollTimer.Stop();
RevealTimer.Stop();
return;
}
}
private void RevealTimer_Tick(object sender, object e)
{
CurrentChar ;
}
public LetterRevealTextBlock()
{
this.InitializeComponent();
ScrollTimer.Tick = ScrollTimer_Tick;
RevealTimer.Tick = RevealTimer_Tick;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/506320.html