需求
Form 包含一個 Panel、一個 PictureBox、一個 Label。點擊 PictureBox 或 Label 時,將其加入 Panel。但 Panel 同一時間只能包含兩者其中之一:若已有 PictureBox 則不可加 Label,反之亦然。
解決方案:遍歷 Controls 集合
private void AddControlToPanel(Control controlToAdd)
{
// 1. 檢查 Panel 是否已包含 PictureBox
bool hasPictureBox = panel1.Controls.OfType().Any();
// 2. 檢查 Panel 是否已包含 Label
bool hasLabel = panel1.Controls.OfType
關鍵點解析
panel.Controls.OfType<T>():LINQ 擴充方法,型別安全篩選指定類型控制項,比 foreach (Control c in panel.Controls) if (c is T) 更簡潔。
- 控制項只能有一個 Parent:若直接 `panel.Controls.Add(existingControl)` 會從原容器移除。上方範例建立**新實例**避免此問題;若需移動原控制項,邏輯相同。
Dock = DockStyle.Fill:讓控制項自動填滿 Panel 客戶區。
進階:使用 Tag 或 Dictionary 追蹤狀態
若控制項類型多、邏輯複雜,建議用 Dictionary<Type, Control> 或在 Panel 的 Tag 屬性儲存當前狀態,避免每次遍歷。
結論
利用 Controls.OfType<T>() 快速檢查 Panel 內容,配合互斥邏輯即可滿足需求。程式碼簡潔、型別安全、易維護。