早期 QQ 主面板左側按鈕組,點擊不同按鈕切換對應 ListView 內容,且按鈕與列表緊貼頂/底邊緣。本文揭秘核心技巧:多按鈕 + 單 ListView,利用 Dock、BringToFront/SendToBack 動態調整 Z 軸與停靠邊緣,實現無閃爍切換。
button1、button2、button3(垂直排列)ListView:listView1(大圖標模式,綁定 ImageList)using System;
using System.Windows.Forms;
namespace QQStylePanel
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// 初始化 ListView
listView1.LargeImageList = imageList1;
listView1.View = View.LargeIcon;
LoadFriends("初始群組");
}
// 按鈕 1:好友列表
private void button1_Click(object sender, EventArgs e)
{
SwitchPanel(button1, button2, button3, "好友群組");
}
// 按鈕 2:陌生人
private void button2_Click(object sender, EventArgs e)
{
SwitchPanel(button2, button1, button3, "陌生人群組");
}
// 按鈕 3:黑名單
private void button3_Click(object sender, EventArgs e)
{
SwitchPanel(button3, button1, button2, "黑名單群組");
}
///
/// 統一面板切換邏輯
///
/// 當前點擊按鈕
/// 其它按鈕 1
/// 其它按鈕 2
/// 群組名稱(用於載入不同數據)
private void SwitchPanel(Button activeBtn, Button otherBtn1, Button otherBtn2, string groupName)
{
// 1. 讓 ListView 脫離 Dock,準備重新停靠
listView1.Dock = DockStyle.None;
// 2. 當前按鈕置頂
activeBtn.Dock = DockStyle.Top;
activeBtn.BringToFront();
// 3. 其他按鈕送到底部,按順序 Dock Bottom
otherBtn1.SendToBack();
otherBtn1.Dock = DockStyle.Top; // 實際在頂部堆疊
otherBtn2.SendToBack();
otherBtn2.Dock = DockStyle.Bottom;
// 4. ListView 置頂並 Dock Bottom 填充中間
listView1.BringToFront();
listView1.Dock = DockStyle.Bottom;
// 5. 重新載入數據
LoadFriends(groupName);
}
private void LoadFriends(string group)
{
listView1.Clear();
listView1.LargeImageList = imageList1;
switch (group)
{
case "好友群組":
listView1.Items.Add("小豬", "小豬", 0);
listView1.Items.Add("小狗", "小狗", 1);
listView1.Items.Add("嬌嬌", "嬌嬌", 2);
break;
case "陌生人群組":
listView1.Items.Add("北風", "北風", 3);
break;
case "黑名單群組":
listView1.Items.Add("冰雨", "冰雨", 5);
break;
}
}
}
}
| 技巧 | 作用 |
|---|---|
listView1.Dock = DockStyle.None | 重置停靠,避免舊 Dock 干擾新佈局 |
BringToFront / SendToBack | 調整 Z-Order,決定誰在可視頂層 |
按鈕 Dock = Top 疊加 | 多個 Top 停靠按鈕會從上到下自動排列 |
ListView.Dock = Bottom | 佔據剩餘空間,隨窗體縮放自適應 |
TabControl (隱藏標籤) + TabPage:每頁放一個 ListView,切換只需 tabControl.SelectedTab = page,無需手動 Dock 操作。ListBox + DataTemplate + Trigger,分離視圖與數據,支援動畫過渡。BindingSource.Filter,避免重複 Clear/Add。QQPanelDemo/
├── Form1.cs
├── Form1.Designer.cs
├── Program.cs
├── Resources/
│ ├── friend0.png
│ ├── friend1.png
│ ├── friend2.png
│ ├── stranger3.png
│ └── block5.png
└── QQPanelDemo.csproj
Dock + Z-Order 是 WinForms 實現面板無縫切換的經典技法。理解其「脫離 → 重排 → 重新停靠」三步曲,對掌握 WinForms 佈局引擎極有幫助。實際開發中,優先考慮 TabControl 或現代框架,減少手動佈局代碼,提升可維護性。