diff --git a/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.BopomofoSearch.cs b/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.BopomofoSearch.cs
index dcae270..12d459c 100644
--- a/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.BopomofoSearch.cs
+++ b/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.BopomofoSearch.cs
@@ -13,16 +13,22 @@ namespace DualScreenDemo
{
public partial class PrimaryForm
{
+ // 注音歌曲的 PictureBox
private PictureBox pictureBoxZhuYinSongs;
-
+ //存放注音按鈕的陣列
private Button[] phoneticButtonsForSongs;
+ //特殊功能按鈕(修改、清除、關閉)
private Button modifyButtonZhuYinSongs;
private Button clearButtonZhuYinSongs;
private Button closeButtonZhuYinSongs;
+ //用於顯示輸入文字的輸入框
private RichTextBox inputBoxZhuYinSongs;
-
+ ///
+ /// 注音歌曲搜尋按鈕點擊事件
+ ///
private void ZhuyinSearchSongsButton_Click(object sender, EventArgs e)
{
+ //更新搜尋模式按鈕的背景圖
zhuyinSearchSongButton.BackgroundImage = zhuyinSearchSongActiveBackground;
englishSearchSongButton.BackgroundImage = englishSearchSongNormalBackground;
pinyinSearchSongButton.BackgroundImage = pinyinSearchSongNormalBackground;
@@ -30,199 +36,318 @@ namespace DualScreenDemo
handWritingSearchSongButton.BackgroundImage = handWritingSearchSongNormalBackground;
numberSearchSongButton.BackgroundImage = numberSearchSongNormalBackground;
-
+ // 讀取 config.ini 並獲取注音圖片的路徑
var configData = LoadConfigData();
- /* 抓注音圖檔(ZhuYinSongs) 來自configData的資料 */
- /* 要確認路經需確認configData內容值 */
string imagePath = Path.Combine(Application.StartupPath, configData["ImagePaths"]["ZhuYinSongs"]);
-
+ //顯示注音歌曲圖片
ShowImageOnPictureBoxZhuYinSongs(Path.Combine(Application.StartupPath, imagePath));
-
- SetZhuYinSingersAndButtonsVisibility(false);
+ //設定不同模式的UI顯示
+ //SetZhuYinSingersAndButtonsVisibility(false);
SetEnglishSingersAndButtonsVisibility(false);
SetPinYinSingersAndButtonsVisibility(false);
SetHandWritingForSingersAndButtonsVisibility(false);
SetZhuYinSongsAndButtonsVisibility(true);
pictureBoxZhuYinSongs.Visible = true;
}
- /* 初始化拼音按鈕 */
+ ///
+ /// 初始化注音按鈕 (Phonetic Buttons) 並載入其對應的圖片與座標
+ /// 1. 讀取 config.ini 設定檔,獲取按鈕的相關數據 (符號、座標、圖片)
+ /// 2. 解析注音符號並儲存至 phoneticSymbols 陣列
+ /// 3. 解析按鈕的座標資訊,存入 phoneticButtonCoords
+ /// 4. 解析按鈕的圖片 (正常狀態、按下狀態、懸停狀態),存入 phoneticButtonImages。
+ /// 5. 依序建立 35 個注音按鈕,並套用對應的圖片與事件處理函數。
+ ///
private void InitializePhoneticButtonsForSongs()
{
+ // 1. 從設定檔 (config.ini) 讀取配置數據,包含按鈕座標、圖片等
var data = LoadConfigData();
+ // 2. 讀取注音符號列表,這些符號將用於顯示在按鈕上
phoneticSymbols = LoadPhoneticSymbols(data);
+
+ // 3. 從設定檔載入 **注音按鈕的座標**,每個按鈕都有對應的 (X, Y, Width, Height)
phoneticButtonCoords = LoadButtonCoordinates(data, "PhoneticButtonCoordinates", 35);
+
+ // 4. 從設定檔載入 **注音按鈕的圖片**,每個按鈕都有正常、按下、懸停三種狀態
phoneticButtonImages = LoadButtonImages(data, "PhoneticButtonImages", 35);
+ // 5. 建立 35 個注音按鈕的陣列 (每個按鈕對應一個注音符號)
phoneticButtonsForSongs = new Button[35];
+
+ // 6. 迴圈建立所有的注音按鈕
for (int i = 0; i < 35; i++)
{
+ // 取得當前按鈕的圖片 (從已載入的 phoneticButtonImages 字典中獲取)
var buttonImages = phoneticButtonImages[$"button{i}"];
- CreatePhoneticButtonForSongs(i, buttonImages.normal, buttonImages.mouseDown, buttonImages.mouseOver);
+
+ // 建立單個注音按鈕,並設定其圖片與點擊事件
+ CreatePhoneticButtonForSongs(
+ i, // 按鈕索引 (對應於 phoneticSymbols)
+ buttonImages.normal, // 按鈕的普通狀態圖片
+ buttonImages.mouseDown, // 按下時的圖片
+ buttonImages.mouseOver // 滑鼠懸停時的圖片
+ );
}
}
- /* 按鈕設置顯示方式 可參考按鈕事件寫法 */
+
+
+ ///
+ /// 建立單個注音按鈕,並設定其圖片、大小、位置,以及滑鼠事件。
+ ///
+ /// 按鈕索引 (對應於 phoneticSymbols)
+ /// 按鈕的普通狀態圖片路徑
+ /// 按鈕被按下時的圖片路徑
+ /// 滑鼠懸停時的圖片路徑
private void CreatePhoneticButtonForSongs(int index, string normalImagePath, string mouseDownImagePath, string mouseOverImagePath)
{
try
{
-
-
+ // 1. 創建按鈕並初始化屬性
phoneticButtonsForSongs[index] = new Button
{
- Name = $"phoneticButton_{phoneticSymbols[index]}",
- BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath)),
- BackgroundImageLayout = ImageLayout.Stretch,
- FlatStyle = FlatStyle.Flat,
- FlatAppearance = { BorderSize = 0 }
+ Name = $"phoneticButton_{phoneticSymbols[index]}", // 設定按鈕名稱,方便識別
+ BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath)), // 設定預設背景圖
+ BackgroundImageLayout = ImageLayout.Stretch, // 背景圖自動填滿按鈕
+ FlatStyle = FlatStyle.Flat, // 設定按鈕為扁平樣式
+ FlatAppearance = { BorderSize = 0 } // 移除按鈕的邊框
};
- ResizeAndPositionButton(phoneticButtonsForSongs[index], phoneticButtonCoords[index].X, phoneticButtonCoords[index].Y,
- phoneticButtonCoords[index].Width, phoneticButtonCoords[index].Height);
+ // 2. 設定按鈕的大小與位置
+ ResizeAndPositionButton(
+ phoneticButtonsForSongs[index],
+ phoneticButtonCoords[index].X,
+ phoneticButtonCoords[index].Y,
+ phoneticButtonCoords[index].Width,
+ phoneticButtonCoords[index].Height
+ );
+ // 3. 載入三種狀態的圖片
Image normalImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath));
Image mouseDownImage = Image.FromFile(Path.Combine(Application.StartupPath, mouseDownImagePath));
Image mouseOverImage = Image.FromFile(Path.Combine(Application.StartupPath, mouseOverImagePath));
+ // 4. 設定滑鼠事件,改變背景圖
phoneticButtonsForSongs[index].MouseDown += (s, e) => phoneticButtonsForSongs[index].BackgroundImage = mouseDownImage;
phoneticButtonsForSongs[index].MouseUp += (s, e) => phoneticButtonsForSongs[index].BackgroundImage = normalImage;
phoneticButtonsForSongs[index].MouseEnter += (s, e) => phoneticButtonsForSongs[index].BackgroundImage = mouseOverImage;
phoneticButtonsForSongs[index].MouseLeave += (s, e) => phoneticButtonsForSongs[index].BackgroundImage = normalImage;
+
+ // 5. 設定按鈕的點擊事件 (當按下按鈕時,觸發 PhoneticButton_Click)
phoneticButtonsForSongs[index].Click += PhoneticButton_Click;
+
+ // 6. 存入對應的注音符號,方便之後的處理
phoneticButtonsForSongs[index].Tag = phoneticSymbols[index];
+ // 7. 將按鈕加入視窗
this.Controls.Add(phoneticButtonsForSongs[index]);
-
-
}
catch (Exception ex)
{
+ // 例外處理,確保按鈕建立失敗時不影響其他部分
Console.WriteLine($"Error creating button at index {index}: {ex.Message}");
}
}
+
+ ///
+ /// 初始化注音輸入界面的所有按鈕和輸入框。
+ ///
private void InitializeButtonsForZhuYinSongs()
{
+ // 1. 從設定檔 (config.ini) 載入注音符號
LoadPhoneticSymbolsFromConfig();
+
+ // 2. 初始化 35 個注音按鈕
InitializePhoneticButtonsForSongs();
+
+ // 3. 初始化特殊按鈕 (例如:刪除、確定、返回按鈕)
InitializeSpecialButtonsForZhuYinSongs();
+
+ // 4. 初始化輸入框 (用於顯示使用者輸入的注音符號)
InitializeInputBoxZhuYinSongs();
}
+
+ ///
+ /// 初始化注音輸入界面的特殊按鈕,包括「修改」、「清除」和「關閉」。
+ ///
private void InitializeSpecialButtonsForZhuYinSongs()
{
-
+ // 1. 初始化「修改」按鈕 (刪除上一個輸入的注音符號)
InitializeModifyButtonZhuYinSongs();
-
+ // 2. 初始化「清除」按鈕 (清空所有輸入內容)
InitializeClearButtonZhuYinSongs();
-
+ // 3. 初始化「關閉」按鈕 (關閉注音輸入介面)
InitializeCloseButtonZhuYinSongs();
}
+
+ ///
+ /// 初始化「修改」按鈕,讓使用者可以刪除上一個輸入的注音符號。
+ ///
private void InitializeModifyButtonZhuYinSongs()
{
+ // 1. 讀取設定檔 (config.ini) 來獲取特殊按鈕的座標與圖像資訊
var data = LoadConfigData();
+
+ // 2. 從設定檔讀取「修改」按鈕的座標數據
modifyButtonZhuYinCoords = LoadSpecialButtonCoordinates(data, "SpecialButtonCoordinates", "modifyButtonZhuYinSongs");
+
+ // 3. 從設定檔讀取「修改」按鈕的圖像 (Normal、MouseOver、MouseDown)
var buttonImages = LoadButtonImages(data, "ModifyButtonImagesZhuYin");
+ // 4. 使用座標與圖像來建立「修改」按鈕,並綁定點擊事件
modifyButtonZhuYinSongs = CreateSpecialButton(
- "btnModifyZhuYinSongs",
- modifyButtonZhuYinCoords,
- buttonImages.normal,
- buttonImages.mouseOver,
- buttonImages.mouseDown,
- ModifyButtonZhuYinSongs_Click
+ "btnModifyZhuYinSongs", // 按鈕名稱
+ modifyButtonZhuYinCoords, // 按鈕座標
+ buttonImages.normal, // 預設 (normal) 圖像
+ buttonImages.mouseOver, // 滑鼠移過 (hover) 圖像
+ buttonImages.mouseDown, // 按下 (pressed) 圖像
+ ModifyButtonZhuYinSongs_Click // 綁定按鈕點擊事件
);
}
+
+ ///
+ /// 「修改」按鈕的點擊事件,刪除輸入框內的最後一個注音符號。
+ ///
private void ModifyButtonZhuYinSongs_Click(object sender, EventArgs e)
{
-
+ // 1. 確保輸入框 (inputBoxZhuYinSongs) 存在於目前的視窗控制項中
if (this.Controls.Contains(inputBoxZhuYinSongs) && inputBoxZhuYinSongs.Text.Length > 0)
{
+ // 2. 刪除輸入框中的最後一個字元 (即移除最後一個注音符號)
inputBoxZhuYinSongs.Text = inputBoxZhuYinSongs.Text.Substring(0, inputBoxZhuYinSongs.Text.Length - 1);
}
}
+ ///
+ /// 初始化「清除」按鈕,並從設定檔載入其位置與圖片資源。
+ ///
private void InitializeClearButtonZhuYinSongs()
{
+ // 1. 從設定檔 (config.ini) 讀取配置數據
var data = LoadConfigData();
+
+ // 2. 讀取「清除」按鈕的座標設定 (從 "SpecialButtonCoordinates" 內的 "clearButtonZhuYinSongs" 取得)
clearButtonZhuYinCoords = LoadSpecialButtonCoordinates(data, "SpecialButtonCoordinates", "clearButtonZhuYinSongs");
+
+ // 3. 讀取「清除」按鈕的圖片 (正常、滑鼠懸停、按下狀態)
var buttonImages = LoadButtonImages(data, "ClearButtonImagesZhuYin");
+ // 4. 建立「清除」按鈕,並設定對應的事件處理函式 (ClearButtonZhuYinSongs_Click)
clearButtonZhuYinSongs = CreateSpecialButton(
- "btnClearZhuYinSongs",
- clearButtonZhuYinCoords,
- buttonImages.normal,
- buttonImages.mouseOver,
- buttonImages.mouseDown,
- ClearButtonZhuYinSongs_Click
+ "btnClearZhuYinSongs", // 按鈕名稱
+ clearButtonZhuYinCoords, // 按鈕座標與大小
+ buttonImages.normal, // 正常狀態圖片
+ buttonImages.mouseOver, // 滑鼠懸停圖片
+ buttonImages.mouseDown, // 按下時圖片
+ ClearButtonZhuYinSongs_Click // 點擊事件處理函式
);
}
+ ///
+ /// 當使用者點擊「清除」按鈕時,將輸入框 (inputBoxZhuYinSongs) 的內容清空。
+ ///
+ /// 觸發事件的按鈕。
+ /// 事件參數。
private void ClearButtonZhuYinSongs_Click(object sender, EventArgs e)
- {
+ {
+ // 1. 確保視窗內包含「注音輸入框」(inputBoxZhuYinSongs),且輸入框內有文字
if (this.Controls.Contains(inputBoxZhuYinSongs) && inputBoxZhuYinSongs.Text.Length > 0)
{
+ // 2. 清空輸入框內容
inputBoxZhuYinSongs.Text = "";
}
}
+
+ ///
+ /// 初始化注音輸入的關閉按鈕,從設定檔讀取按鈕座標與圖片,並設置點擊事件
+ ///
private void InitializeCloseButtonZhuYinSongs()
{
+ // 讀取設定檔數據
var data = LoadConfigData();
+
+ // 從設定檔讀取關閉按鈕的座標
closeButtonZhuYinCoords = LoadSpecialButtonCoordinates(data, "SpecialButtonCoordinates", "closeButtonZhuYinSongs");
+
+ // 從設定檔讀取關閉按鈕的圖片
var buttonImages = LoadButtonImages(data, "CloseButtonImagesZhuYin");
+ // 創建關閉按鈕並綁定點擊事件
closeButtonZhuYinSongs = CreateSpecialButton(
- "btnCloseZhuYinSongs",
- closeButtonZhuYinCoords,
- buttonImages.normal,
- buttonImages.mouseOver,
- buttonImages.mouseDown,
- CloseButtonZhuYinSongs_Click
+ "btnCloseZhuYinSongs", // 按鈕名稱
+ closeButtonZhuYinCoords, // 按鈕座標
+ buttonImages.normal, // 正常狀態圖片
+ buttonImages.mouseOver, // 滑鼠懸停圖片
+ buttonImages.mouseDown, // 按下圖片
+ CloseButtonZhuYinSongs_Click // 綁定點擊事件
);
}
+
+ ///
+ /// 關閉注音輸入介面,隱藏相關 UI 元件
+ ///
+ /// 觸發事件的按鈕 (關閉按鈕)
+ /// 事件參數
private void CloseButtonZhuYinSongs_Click(object sender, EventArgs e)
{
+ // 隱藏注音輸入的圖片
pictureBoxZhuYinSongs.Visible = false;
+
+ // 隱藏注音輸入的所有按鈕與介面元素
SetZhuYinSongsAndButtonsVisibility(false);
}
+ ///
+ /// 初始化注音輸入框 (RichTextBox),設定外觀、事件處理及位置大小
+ ///
private void InitializeInputBoxZhuYinSongs()
{
try
{
+ // 讀取輸入框的配置,例如字體、顏色、大小等
LoadInputBoxConfig();
+ // 建立注音輸入框並套用讀取到的設定
inputBoxZhuYinSongs = new RichTextBox
{
Name = "inputBoxZhuYinSongs",
- ForeColor = inputBoxForeColor,
- Font = new Font(inputBoxFontName, inputBoxFontSize, inputBoxFontStyle),
- ScrollBars = RichTextBoxScrollBars.None
+ ForeColor = inputBoxForeColor, // 設定文字顏色
+ Font = new Font(inputBoxFontName, inputBoxFontSize, inputBoxFontStyle), // 設定字體
+ ScrollBars = RichTextBoxScrollBars.None // 禁用滾動條
};
- ResizeAndPositionControl(inputBoxZhuYinSongs, inputBoxZhuYinCoords.X, inputBoxZhuYinCoords.Y, inputBoxZhuYinCoords.Width, inputBoxZhuYinCoords.Height);
+ // 調整輸入框大小與位置
+ ResizeAndPositionControl(inputBoxZhuYinSongs, inputBoxZhuYinCoords.X, inputBoxZhuYinCoords.Y,
+ inputBoxZhuYinCoords.Width, inputBoxZhuYinCoords.Height);
+ // 設定文字變更事件,用來即時篩選歌曲
inputBoxZhuYinSongs.TextChanged += (sender, e) =>
{
- /* 搜尋結果顯示到前歌單點選 */
- string searchText = inputBoxZhuYinSongs.Text;
+ string searchText = inputBoxZhuYinSongs.Text; // 取得輸入內容
+
+ // 根據輸入的注音篩選歌曲清單
var searchResults = allSongs.Where(song => song.PhoneticNotation.StartsWith(searchText)).ToList();
+
+ // 重置分頁
currentPage = 0;
currentSongList = searchResults;
totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage);
+ // 更新多頁面面板的內容
multiPagePanel.currentPageIndex = 0;
multiPagePanel.LoadSongs(currentSongList);
};
+ // 將輸入框加入到 UI 控制項
this.Controls.Add(inputBoxZhuYinSongs);
}
catch (Exception ex)
@@ -230,51 +355,95 @@ namespace DualScreenDemo
Console.WriteLine("Error initializing inputBoxZhuYinSongs: " + ex.Message);
}
}
-
+
+ ///
+ /// 存儲 PictureBoxZhuYinSongs 的座標與尺寸信息。
+ ///
+ ///
+ /// 此元組包含以下四個值:
+ /// X:X 座標
+ /// , Y:Y 座標
+ /// , Width:寬度
+ /// , Height:高度
+ ///
private (int X, int Y, int Width, int Height) pictureBoxZhuYinSongCoords;
+ ///
+ /// 從設定檔 (config.ini) 讀取 PictureBoxZhuYinSongs 的座標與尺寸
+ ///
private void LoadPictureBoxZhuYinSongCoordsFromConfig()
{
+ // 建立 INI 檔案解析器
var parser = new FileIniDataParser();
+
+ // 讀取 config.ini 設定檔的內容
IniData data = parser.ReadFile("config.ini");
+ // 取得 "PictureBoxZhuYinSongs" 段落的設定數據
var coords = data["PictureBoxZhuYinSongs"];
+
+ // 解析座標與尺寸,並存入 pictureBoxZhuYinSongCoords
pictureBoxZhuYinSongCoords = (
- int.Parse(coords["X"]),
- int.Parse(coords["Y"]),
- int.Parse(coords["Width"]),
- int.Parse(coords["Height"])
+ int.Parse(coords["X"]), // 讀取 X 座標
+ int.Parse(coords["Y"]), // 讀取 Y 座標
+ int.Parse(coords["Width"]), // 讀取寬度
+ int.Parse(coords["Height"]) // 讀取高度
);
}
+
+ ///
+ /// 在 pictureBoxZhuYinSongs 上顯示指定路徑的圖片,並根據設定調整其大小與位置。
+ ///
+ /// 要顯示的圖片檔案路徑
private void ShowImageOnPictureBoxZhuYinSongs(string imagePath)
{
-
+ // 從 config.ini 讀取 PictureBox 的座標與尺寸
LoadPictureBoxZhuYinSongCoordsFromConfig();
-
+ // 讀取圖片檔案並載入 Bitmap 物件
Bitmap originalImage = new Bitmap(imagePath);
-
- Rectangle displayArea = new Rectangle(pictureBoxZhuYinSongCoords.X, pictureBoxZhuYinSongCoords.Y, pictureBoxZhuYinSongCoords.Width, pictureBoxZhuYinSongCoords.Height);
+ // 設定圖片顯示區域,使用從設定檔讀取的座標與尺寸
+ Rectangle displayArea = new Rectangle(
+ pictureBoxZhuYinSongCoords.X,
+ pictureBoxZhuYinSongCoords.Y,
+ pictureBoxZhuYinSongCoords.Width,
+ pictureBoxZhuYinSongCoords.Height
+ );
-
+ // 設定 PictureBox 的圖片
pictureBoxZhuYinSongs.Image = originalImage;
-
- ResizeAndPositionPictureBox(pictureBoxZhuYinSongs, displayArea.X, displayArea.Y, displayArea.Width, displayArea.Height);
+ // 調整 PictureBox 的大小與位置,使其符合設定
+ ResizeAndPositionPictureBox(
+ pictureBoxZhuYinSongs,
+ displayArea.X,
+ displayArea.Y,
+ displayArea.Width,
+ displayArea.Height
+ );
+ // 顯示 PictureBox
pictureBoxZhuYinSongs.Visible = true;
}
+
+ ///
+ /// 設定注音歌曲相關的 PictureBox、按鈕和輸入框的可見性。
+ ///
+ /// 若為 true,則顯示這些控件;否則隱藏。
private void SetZhuYinSongsAndButtonsVisibility(bool isVisible)
{
+ // 定義要執行的操作,設定各控件的可見性
System.Action action = () =>
{
try
{
+ // 暫停佈局邏輯,防止在調整控件可見性時觸發不必要的佈局計算,提升性能
SuspendLayout();
+ // 檢查並設定 pictureBoxZhuYinSongs 的可見性
if (pictureBoxZhuYinSongs == null)
{
Console.WriteLine("pictureBoxZhuYinSongs is null");
@@ -285,6 +454,7 @@ namespace DualScreenDemo
if (isVisible) pictureBoxZhuYinSongs.BringToFront();
}
+ // 檢查並設定 phoneticButtonsForSongs 陣列中每個按鈕的可見性
if (phoneticButtonsForSongs == null)
{
Console.WriteLine("phoneticButtonsForSongs is null");
@@ -305,6 +475,7 @@ namespace DualScreenDemo
}
}
+ // 檢查並設定 modifyButtonZhuYinSongs 的可見性
if (modifyButtonZhuYinSongs == null)
{
Console.WriteLine("modifyButtonZhuYinSongs is null");
@@ -315,6 +486,7 @@ namespace DualScreenDemo
if (isVisible) modifyButtonZhuYinSongs.BringToFront();
}
+ // 檢查並設定 clearButtonZhuYinSongs 的可見性
if (clearButtonZhuYinSongs == null)
{
Console.WriteLine("clearButtonZhuYinSongs is null");
@@ -325,6 +497,7 @@ namespace DualScreenDemo
if (isVisible) clearButtonZhuYinSongs.BringToFront();
}
+ // 檢查並設定 closeButtonZhuYinSongs 的可見性
if (closeButtonZhuYinSongs == null)
{
Console.WriteLine("closeButtonZhuYinSongs is null");
@@ -335,6 +508,7 @@ namespace DualScreenDemo
if (isVisible) closeButtonZhuYinSongs.BringToFront();
}
+ // 檢查並設定 inputBoxZhuYinSongs 的可見性
if (inputBoxZhuYinSongs == null)
{
Console.WriteLine("inputBoxZhuYinSongs is null");
@@ -345,10 +519,12 @@ namespace DualScreenDemo
if (isVisible) inputBoxZhuYinSongs.BringToFront();
}
+ // 恢復佈局邏輯,允許佈局計算
ResumeLayout();
- PerformLayout();
+ // 強制控件立即執行佈局邏輯,確保佈局更新立即生效
+ PerformLayout();
-
+ // 刷新各控件,確保其狀態立即更新
pictureBoxZhuYinSongs?.Refresh();
if (phoneticButtonsForSongs != null)
{
@@ -364,10 +540,12 @@ namespace DualScreenDemo
}
catch (Exception ex)
{
+ // 捕捉並輸出異常資訊,方便除錯
Console.WriteLine("Error in SetZhuYinSongsAndButtonsVisibility: " + ex.Message);
}
};
+ // 如果當前執行緒需要呼叫 Invoke 方法才能修改控件,則使用 Invoke
if (this.InvokeRequired)
{
this.Invoke(action);
@@ -377,5 +555,6 @@ namespace DualScreenDemo
action();
}
}
+
}
}
\ No newline at end of file
diff --git a/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.PinyinSearch.cs b/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.PinyinSearch.cs
index 5a0d7f5..d406e69 100644
--- a/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.PinyinSearch.cs
+++ b/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.PinyinSearch.cs
@@ -20,7 +20,9 @@ namespace DualScreenDemo
private Button closeButtonPinYinSongs;
// 用於顯示輸入文字的輸入框
private RichTextBox inputBoxPinYinSongs;
- // 拼音歌曲搜尋按鈕點擊事件
+ ///
+ /// 拼音歌曲搜尋按鈕點擊事件
+ ///
private void PinyinSearchSongsButton_Click(object sender, EventArgs e)
{
// 更新搜尋模式按鈕的背景圖
@@ -124,9 +126,9 @@ namespace DualScreenDemo
///
/// 初始化拼音輸入的特殊功能按鈕,包括:
- /// 1. 修改按鈕 - 刪除輸入框中的最後一個字母
- /// 2. 清除按鈕 - 清空輸入框的內容
- /// 3. 關閉按鈕 - 隱藏拼音輸入的 UI 元件
+ /// 1. 修改按鈕 - 刪除輸入框中的最後一個字母
+ /// 2. 清除按鈕 - 清空輸入框的內容
+ /// 3. 關閉按鈕 - 隱藏拼音輸入的 UI 元件
///
private void InitializeSpecialButtonsForPinYinSongs()
{
@@ -167,11 +169,11 @@ namespace DualScreenDemo
}
///
- /// 「修改」按鈕點擊事件:刪除拼音輸入框 (`inputBoxPinYinSongs`) 中的最後一個字母。
+ /// 「修改」按鈕點擊事件:刪除拼音輸入框 (inputBoxPinYinSongs) 中的最後一個字母。
///
private void ModifyButtonPinYinSongs_Click(object sender, EventArgs e)
{
- // 確保 `inputBoxPinYinSongs` 存在於視窗控制項集合內,且輸入框內有文字
+ // 確保 inputBoxPinYinSongs 存在於視窗控制項集合內,且輸入框內有文字
if (this.Controls.Contains(inputBoxPinYinSongs) && inputBoxPinYinSongs.Text.Length > 0)
{
// 刪除輸入框內的最後一個字母
@@ -181,7 +183,7 @@ namespace DualScreenDemo
///
- /// 初始化「清除」按鈕 (`clearButtonPinYinSongs`),用於清空拼音輸入框 (`inputBoxPinYinSongs`)。
+ /// 初始化「清除」按鈕 (clearButtonPinYinSongs),用於清空拼音輸入框 (inputBoxPinYinSongs)。
///
private void InitializeClearButtonPinYinSongs()
{
@@ -220,7 +222,7 @@ namespace DualScreenDemo
}
///
- /// 初始化「關閉」按鈕 (`closeButtonPinYinSongs`),用於隱藏拼音輸入介面。
+ /// 初始化「關閉」按鈕 (closeButtonPinYinSongs),用於隱藏拼音輸入介面。
///
private void InitializeCloseButtonPinYinSongs()
{
@@ -258,7 +260,7 @@ namespace DualScreenDemo
}
///
- /// 初始化拼音輸入框 (`RichTextBox`),並從 `config.ini` 讀取相關設定。
+ /// 初始化拼音輸入框 (RichTextBox),並從 config.ini 讀取相關設定。
///
private void InitializeInputBoxPinYinSongs()
{
@@ -268,13 +270,13 @@ namespace DualScreenDemo
var parser = new FileIniDataParser();
// 配置解析器的參數
- parser.Parser.Configuration.AssigmentSpacer = ""; // 設定 `=` 兩側沒有空格
- parser.Parser.Configuration.CommentString = "#"; // 使用 `#` 作為註解符號
+ parser.Parser.Configuration.AssigmentSpacer = ""; // 設定 = 兩側沒有空格
+ parser.Parser.Configuration.CommentString = "#"; // 使用 # 作為註解符號
parser.Parser.Configuration.CaseInsensitive = true; // 參數名稱不區分大小寫
IniData data; // 儲存解析後的 INI 數據
- // 讀取 `config.ini` 文件,使用 UTF-8 編碼
+ // 讀取 config.ini 文件,使用 UTF-8 編碼
using (var reader = new StreamReader("config.ini", System.Text.Encoding.UTF8))
{
data = parser.ReadData(reader);
@@ -292,7 +294,7 @@ namespace DualScreenDemo
FontStyle fontStyle = (FontStyle)Enum.Parse(typeof(FontStyle), data["InputBoxPinYinSongs"]["FontStyle"]); // 字體樣式
Color foreColor = Color.FromName(data["InputBoxPinYinSongs"]["ForeColor"]); // 文字顏色
- // 創建拼音輸入框 (`RichTextBox`)
+ // 創建拼音輸入框 (RichTextBox)
inputBoxPinYinSongs = new RichTextBox
{
Visible = false, // 預設為隱藏
@@ -308,7 +310,7 @@ namespace DualScreenDemo
// 設定輸入框的位置與大小
ResizeAndPositionControl(inputBoxPinYinSongs, x, y, width, height);
- // **綁定 `TextChanged` 事件 (當輸入內容改變時觸發搜尋)**
+ // **綁定 TextChanged 事件 (當輸入內容改變時觸發搜尋)**
inputBoxPinYinSongs.TextChanged += (sender, e) =>
{
string searchText = inputBoxPinYinSongs.Text;
@@ -335,7 +337,7 @@ namespace DualScreenDemo
}
}
///
- /// 存儲 `PictureBoxPinYinSongs` 的座標與尺寸信息。
+ /// 存儲 PictureBoxPinYinSongs 的座標與尺寸信息。
///
///
/// 此元組包含以下四個值:
@@ -347,20 +349,20 @@ namespace DualScreenDemo
private (int X, int Y, int Width, int Height) pictureBoxPinYinSongCoords;
///
- /// 從 `config.ini` 配置檔案中載入 `PictureBoxPinYinSongs` 的座標與尺寸設定。
+ /// 從 config.ini 配置檔案中載入 PictureBoxPinYinSongs 的座標與尺寸設定。
///
private void LoadPictureBoxPinYinSongCoordsFromConfig()
{
// 創建一個 INI 檔案解析器
var parser = new FileIniDataParser();
- // 讀取 `config.ini` 文件並解析成 `IniData` 對象
+ // 讀取 config.ini 文件並解析成 IniData 對象
IniData data = parser.ReadFile("config.ini");
- // 取得 `PictureBoxPinYinSongs` 區段的設定值
+ // 取得 PictureBoxPinYinSongs 區段的設定值
var coords = data["PictureBoxPinYinSongs"];
- // 解析 `X`, `Y`, `Width`, `Height`,並存入 `pictureBoxPinYinSongCoords`
+ // 解析 X, Y, Width, Height,並存入 pictureBoxPinYinSongCoords
pictureBoxPinYinSongCoords = (
int.Parse(coords["X"]), // 解析 X 座標
int.Parse(coords["Y"]), // 解析 Y 座標
@@ -388,10 +390,10 @@ namespace DualScreenDemo
pictureBoxPinYinSongCoords.Height // 設定 高度
);
- // 將載入的圖片設定為 `pictureBoxPinYinSongs` 的影像
+ // 將載入的圖片設定為 pictureBoxPinYinSongs 的影像
pictureBoxPinYinSongs.Image = originalImage;
- // 調整 `PictureBox` 的大小與位置,使其符合 `displayArea` 的設定
+ // 調整 PictureBox 的大小與位置,使其符合 displayArea 的設定
ResizeAndPositionPictureBox(
pictureBoxPinYinSongs,
displayArea.X,
@@ -400,7 +402,7 @@ namespace DualScreenDemo
displayArea.Height
);
- // 顯示 `PictureBox`
+ // 顯示 PictureBox
pictureBoxPinYinSongs.Visible = true;
}
@@ -416,7 +418,7 @@ namespace DualScreenDemo
// 暫停佈局更新,以防止 UI 閃爍或重繪時出現異常
SuspendLayout();
- // 設定 `pictureBoxPinYinSongs` 的可見性
+ // 設定 pictureBoxPinYinSongs 的可見性
pictureBoxPinYinSongs.Visible = isVisible;
if (isVisible) pictureBoxPinYinSongs.BringToFront(); // 確保顯示時位於最前方
@@ -427,25 +429,25 @@ namespace DualScreenDemo
if (isVisible) button.BringToFront();
}
- // 設定 `modifyButtonPinYinSongs` (修改按鈕) 的可見性
+ // 設定 modifyButtonPinYinSongs (修改按鈕) 的可見性
if (modifyButtonPinYinSongs != null)
{
modifyButtonPinYinSongs.Visible = isVisible;
if (isVisible) modifyButtonPinYinSongs.BringToFront();
}
- // 設定 `clearButtonPinYinSongs` (清除按鈕) 的可見性
+ // 設定 clearButtonPinYinSongs (清除按鈕) 的可見性
if (clearButtonPinYinSongs != null)
{
clearButtonPinYinSongs.Visible = isVisible;
if (isVisible) clearButtonPinYinSongs.BringToFront();
}
- // 設定 `closeButtonPinYinSongs` (關閉按鈕) 的可見性
+ // 設定 closeButtonPinYinSongs (關閉按鈕) 的可見性
closeButtonPinYinSongs.Visible = isVisible;
if (isVisible) closeButtonPinYinSongs.BringToFront();
- // 設定 `inputBoxPinYinSongs` (輸入框) 的可見性
+ // 設定 inputBoxPinYinSongs (輸入框) 的可見性
inputBoxPinYinSongs.Visible = isVisible;
if (isVisible) inputBoxPinYinSongs.BringToFront();
@@ -453,7 +455,7 @@ namespace DualScreenDemo
ResumeLayout();
PerformLayout();
- // 刷新 `pictureBoxPinYinSongs`,確保畫面更新
+ // 刷新 pictureBoxPinYinSongs,確保畫面更新
pictureBoxPinYinSongs.Refresh();
// 刷新拼音字母按鈕