C#使用迭代器實(shí)現(xiàn)文字動(dòng)態(tài)效果的示例代碼
一、涉及到的知識(shí)點(diǎn)
1.GDI+
GDI+主要用于在窗體上繪制各種圖形圖像。
GDI+的核心是Graphics類,該類表示GDI+繪圖表面,它提供將對(duì)象繪制到顯示設(shè)備的方法。Graphics類封裝了繪制直線、曲線、圖形、圖像和文本的方法,它是進(jìn)行一切GDI+操作的基礎(chǔ)類。
本實(shí)例使用Graphics類的DrawString方法來(lái)繪制動(dòng)態(tài)的文字,該方法常用的語(yǔ)法格式如下:
public void DrawString(string s,Font font,Brush brush,PointF point)
參數(shù)說(shuō)明
s:要繪制的字符串。
font:定義字符串的文本格式。
brush:確定所繪制文本的顏色和紋理。
point:指定所繪制文本的左上角。
2.Thread類
運(yùn)行C#程序時(shí),如果一個(gè)任務(wù)執(zhí)行時(shí)間過(guò)長(zhǎng),會(huì)導(dǎo)致程序主窗體處于“假死”狀態(tài)。為了避免這種情況發(fā)生,可以使用Thread類來(lái)創(chuàng)建多線程,即每一個(gè)線程完成一個(gè)功能,這樣就可以有效地避免程序出現(xiàn)“假死”現(xiàn)象。
本例中使用了
Thread thread; //定義線程,thread = new Thread()方法、thread.Start()、thread.Interrupt()、Thread.Sleep()方法。
其中
thread.Abort(); //已經(jīng)廢棄,用thread.Interrupt();代替。
3.使用IEnumerable()迭代器
詳見本文作者寫的其他文章, C#字符串倒序遍歷:Reverse() vs for循環(huán) vs IEnumerable迭代器 vs List<T> vs List<T>迭代器 vs IList<T> vs IList<T>迭代器
二、實(shí)例
為了使界面具有動(dòng)態(tài)效果,可以在界面中實(shí)現(xiàn)一些特殊文字的動(dòng)態(tài)效果。使用迭代器遍歷文本字符串中的每一個(gè)文字,然后使用GDI+技術(shù)在窗體上以不同的字體樣式依次繪制每一個(gè)文字,以便實(shí)現(xiàn)文字的動(dòng)態(tài)效果。
1.源碼
// 使用迭代器實(shí)現(xiàn)文字的動(dòng)態(tài)效果
// 給窗體添加背景圖
using System.Resources;
namespace _123
{
public partial class Form1 : Form
{
private Panel? panel1;
public Form1()
{
InitializeComponent();
BackgroundImage = Properties.Resources.GetObject("bc");
BackgroundImageLayout = ImageLayout.Stretch;
StartPosition = FormStartPosition.CenterScreen;
Load += Form1_Load;
}
private void Form1_Load(object? sender, EventArgs e)
{
//
// panel1
//
panel1 = new Panel
{
Location = new Point(321, 12),
Name = "panel1",
Size = new Size(250, 83),
TabIndex = 0
};
//
// Form1
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(600, 416);
Controls.Add(panel1);
Name = "Form1";
Text = "使用迭代器實(shí)現(xiàn)文字的動(dòng)態(tài)效果";
//Graphics Car_Paint = panel1.CreateGraphics();//實(shí)例化繪圖對(duì)象
string CartoonString = "編程詞典網(wǎng)"; //定義要繪制的動(dòng)態(tài)文字
Character character = new(); //實(shí)例化自定義類對(duì)象
character.CartoonEffect(panel1, CartoonString);//在窗體上顯示動(dòng)態(tài)文字
}
}
class Character
{
Graphics? graphics; //定義Graphics對(duì)象
static readonly int[] FSize = [20, 25, 30]; //設(shè)置字體的大小
readonly int Str_block = 5; //字體間的間隔
readonly Font Str_Font = new("宋體", FSize[0], FontStyle.Bold);//定義字體樣式
readonly Color Str_Color = Color.Orange; //定義字體顏色
float Str_Width = 0; //獲取字符串的位置
float Str_Height = 0;
float Panel_W = 0; //獲取控件的寬度
float Panel_H = 0; //獲取控件的高度
Color Panel_C; //記錄控件的背景顏色
float Str_Odd_Width = 0;//獲取單個(gè)文字的寬度
Thread? thread; //定義線程
/// <summary>
/// 在Panel控件中繪制動(dòng)畫文字
/// </summary>
/// <param Panel="C_Panel">顯示文字的容器控件</param>
/// <param string="C_Str">文字字符串</param>
public void CartoonEffect(Panel C_Panel, string C_Str)
{
graphics = C_Panel.CreateGraphics();//為控件創(chuàng)建Graphics對(duì)象
Panel_H = C_Panel.Height; //獲取控件的高度
Panel_W = C_Panel.Width; //獲取控件的寬度
Panel_C = C_Panel.BackColor; //獲取控件背景顏色
GetTextInfo(C_Str); //獲取文字的大小及位置
graphics.FillRectangle( //用控件背景填充控件
new SolidBrush(Panel_C), 0, 0, Panel_W, Panel_H);
DrawFullText(C_Str, 0); //繪制文字
//實(shí)例化ParameterizedThreadStart委托線程
thread = new Thread(new ParameterizedThreadStart(DynamicText!));
thread.Start(C_Str); //傳遞一個(gè)字符串的參數(shù)
}
/// <summary>
/// 獲取文字的大小及繪制位置
/// </summary>
/// <param string="C_Str">文字字符串</param>
public void GetTextInfo(string C_Str)
{
SizeF TitSize = graphics!.MeasureString(C_Str, Str_Font); //將繪制的字符串進(jìn)行格式化
Str_Width = TitSize.Width; //獲取字符串的寬度
Str_Height = TitSize.Height; //獲取字符串的高度
Str_Odd_Width = Str_Width / C_Str.Length; //獲取單個(gè)文字的寬度
Str_Width = (Str_Odd_Width + Str_block) * C_Str.Length; //獲取文字的寬度
Str_Width = (Panel_W - Str_Width) / 2F; //使文字居中
Str_Height = Panel_H - Str_Height; //使文字顯示在控件底端
}
/// <summary>
/// 繪制全部文字
/// </summary>
/// <param string="C_Str">繪制的文字字符串</param>
public void DrawFullText(string C_Str, int n)
{
float Str_Place = Str_Width; //單個(gè)字符的位置
for (int i = 0; i < C_Str.Length; i++)//遍歷字符串中的文字
{
if (i != n)
DrawText(C_Str[i].ToString(), Str_Font, Str_Place, Str_Height); //繪制單個(gè)文字
Str_Place += Str_Odd_Width + Str_block; //獲取下一個(gè)文字的位置
}
}
/// <summary>
/// 繪制單個(gè)文字
/// </summary>
/// <param name="C_Odd_Str">單個(gè)文字字符串</param>
/// <param name="S_Font">文本樣式</param>
/// <param name="left"></param>
/// <param name="top"></param>
public void DrawText(string C_Odd_Str, Font S_Font, float left, float top)
{
graphics!.DrawString(C_Odd_Str, S_Font, new SolidBrush(Str_Color), new PointF(left, top));//繪制字符串中單個(gè)文字
}
/// <summary>
/// 通過(guò)迭代器實(shí)現(xiàn)字符串的遍歷
/// </summary>
/// <param string="n">文字字符串</param>
/// <returns>返回單個(gè)文字</returns>
public static IEnumerable<object> Transpose(string n)
{
if (n.Length > 0)
{
foreach (object i in n)
yield return i;
}
}
/// <summary>
/// 繪制動(dòng)態(tài)文字
/// </summary>
/// <param string="C_Str">繪制的文字字符串</param>
public void DynamicText(Object C_Str)
{
float tem_left = 0; //獲取當(dāng)前文字的左端位置
float tem_top = 0; //獲取當(dāng)前文字的頂端位置
float tem_width = 0; //獲取文字的寬度
float tem_high = 0; //獲取文字的高度
float tem_place = Str_Width; //獲取起始文字的位置
Font Tem_Font = new("黑體", FSize[0], FontStyle.Bold);//定義字體樣式
int p = 0; //記錄字符串中文字的索引號(hào)
int Str_Index = 0;
try
{
foreach (object s in Transpose(C_Str.ToString()!))//遍歷字符串
{
for (int i = 1; i < 5; i++)
{
if (i >= 3)
p = Convert.ToInt16(Math.Floor(i / 2F));
else
p = i;
DrawFullText(C_Str.ToString()!, Str_Index);
Tem_Font = new Font("黑體", FSize[p], FontStyle.Bold);//定義字體樣式
SizeF TitSize = graphics!.MeasureString(s.ToString(),Str_Font);//將繪制的單個(gè)文字進(jìn)行格式化
tem_width = TitSize.Width;//獲取文字的寬度
tem_high = TitSize.Height;//獲取文字串的高度
tem_left = tem_place - (tem_width - Str_Odd_Width) / 2F;//獲取文字改變大小后的左端位置
tem_top = Str_Height - (Str_Height - tem_high) / 2F; //獲取文字改變大小后的頂端位置
DrawText(s.ToString()!, Tem_Font, tem_left, tem_top); //繪制單個(gè)文字
Thread.Sleep(200); //待待0.2秒
graphics.FillRectangle(new SolidBrush(Panel_C), 0, 0, Panel_W,Panel_H);//清空繪制的文字
}
tem_place += Str_Odd_Width + Str_block;//計(jì)算下一個(gè)文字的左端位置
Str_Index += 1; //將索引號(hào)定位到下一個(gè)文字
}
DrawFullText(C_Str.ToString()!, -1);//恢復(fù)文字的原始繪制樣式
//實(shí)例化ParameterizedThreadStart委托線程
thread = new Thread(new ParameterizedThreadStart(DynamicText!));
thread.Start(C_Str); //傳遞一個(gè)字符串的參數(shù)
}
catch//這里之所以用異常語(yǔ)句,是在關(guān)閉窗體時(shí)關(guān)閉線程
{
//thread.Abort(); //已經(jīng)廢棄
thread!.Interrupt(); //關(guān)閉線程
}
}
}
}2.生成效果

到此這篇關(guān)于C#使用迭代器實(shí)現(xiàn)文字動(dòng)態(tài)效果的示例代碼的文章就介紹到這了,更多相關(guān)C#文字動(dòng)態(tài)效果內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c#循環(huán)中產(chǎn)生偽隨機(jī)數(shù)
在循環(huán)中產(chǎn)生多個(gè)隨機(jī)數(shù),容易出現(xiàn)連續(xù)相同的數(shù)據(jù),最終的多個(gè)隨機(jī)數(shù)并不隨機(jī),而是帶有某種規(guī)律性。2010-06-06
C#中IList 與 List 的區(qū)別小結(jié)
IList 接口和 List 類是 C# 中用于集合操作的兩個(gè)重要的類型,本文主要介紹了C#中IList 與 List 的區(qū)別小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04
C#中如何使用Winform實(shí)現(xiàn)炫酷的透明動(dòng)畫界面
這篇文章講解了如何使用Winform實(shí)現(xiàn)炫酷的透明動(dòng)畫界面,Winform相對(duì)于Wpf使用更簡(jiǎn)單一些,系統(tǒng)要求更低,需要了解的朋友可以參考下2015-07-07
詳解如何將.NET應(yīng)用轉(zhuǎn)換成Window服務(wù)
這篇文章主要為大家詳細(xì)介紹了如何將.NET8.0應(yīng)用程序轉(zhuǎn)換成Windows服務(wù),文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01
基于C#實(shí)現(xiàn)進(jìn)程回收管理工具
這篇文章主要為大家詳細(xì)介紹了入戶基于C#實(shí)現(xiàn)一個(gè)進(jìn)程回收管理工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
C#基于純數(shù)學(xué)方法遞歸實(shí)現(xiàn)貨幣數(shù)字轉(zhuǎn)換中文功能詳解
這篇文章主要介紹了C#基于純數(shù)學(xué)方法遞歸實(shí)現(xiàn)貨幣數(shù)字轉(zhuǎn)換中文功能,涉及C#針對(duì)字符串的遍歷、轉(zhuǎn)換與數(shù)學(xué)運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2017-02-02

