首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

仿 QQ 面板 WinForm 實作(一):Dock 佈局與分組切換核心邏輯

     編輯:關於C語言

專案背景與設計理念

純 WinForm 實作類 QQ 主面板效果,不使用任何第三方控制項。核心設計:

  • 使用 Dock 屬性而非 Location 定位,實現自適應視窗大小調整
  • 三大控制項協作:Button(分組標題)、ImageList(頭像)、ListView(好友列表,LargeIcon 模式)
  • 透過 BringToFront/SendToBack 控制 Z 軸順序,配合 Dock 切換達成展開/摺疊動畫感

介面結構

MainForm
├── btnMyFriend (Button) - 我的好友
├── btnMyColleague (Button) - 我的同事
├── btnMyStranger (Button) - 我的陌生人
└── listView (ListView) - 好友列表,Dock 填滿剩餘空間

核心程式碼:分組切換邏輯

public partial class MainForm : Form
{
    public MainForm() { InitializeComponent(); }

    private void MainForm_Load(object sender, EventArgs e)
    {
        InitializeLayout();
        LoadFriends("MyFriend"); // 預設顯示好友
    }

    private void InitializeLayout()
    {
        // 初始 Z-order:listView 在最上層,按鈕依序堆疊
        listView.Dock = DockStyle.None;
        btnMyFriend.Dock = DockStyle.Top;
        btnMyColleague.Dock = DockStyle.Bottom;
        btnMyStranger.SendToBack();
        btnMyStranger.Dock = DockStyle.Bottom;
        listView.BringToFront();
        listView.Dock = DockStyle.Fill; // 佔據剩餘空間
        
        listView.LargeImageList = imageList1;
    }

    // 我的好友
    private void btnMyFriend_Click(object sender, EventArgs e)
    {
        ReorderControls(btnMyFriend, DockStyle.Top, 
                        btnMyColleague, DockStyle.Bottom,
                        btnMyStranger, DockStyle.Bottom);
        LoadFriends("MyFriend");
    }

    // 我的同事
    private void btnMyColleague_Click(object sender, EventArgs e)
    {
        ReorderControls(btnMyColleague, DockStyle.Top,
                        btnMyFriend, DockStyle.Top,
                        btnMyStranger, DockStyle.Bottom);
        LoadFriends("MyColleague");
    }

    // 我的陌生人
    private void btnMyStranger_Click(object sender, EventArgs e)
    {
        ReorderControls(btnMyStranger, DockStyle.Top,
                        btnMyColleague, DockStyle.Top,
                        btnMyFriend, DockStyle.Top);
        LoadFriends("MyStranger");
    }

    // 通用重排邏輯
    private void ReorderControls(Button activeBtn, DockStyle activeDock,
                                 Button btn2, DockStyle dock2,
                                 Button btn3, DockStyle dock3)
    {
        listView.Dock = DockStyle.None;
        
        activeBtn.Dock = activeDock;
        btn2.SendToBack(); btn2.Dock = dock2;
        btn3.SendToBack(); btn3.Dock = dock3;
        
        listView.BringToFront();
        listView.Dock = DockStyle.Fill;
    }

    private void LoadFriends(string group)
    {
        listView.Clear();
        listView.Items.Clear();
        
        switch (group)
        {
            case "MyFriend":
                AddFriend("老婆", 5); AddFriend("小蜜", 1); AddFriend("周公", 7);
                AddFriend("情人", 7); AddFriend("麗麗", 6); AddFriend("花花", 8);
                AddFriend("貝貝", 9); break;
            case "MyColleague":
                AddFriend("老板", 2); AddFriend("董事長", 3); AddFriend("組長", 4);
                AddFriend("班長", 17); AddFriend("婦女主任", 16); AddFriend("行政主管", 15);
                AddFriend("樓道大媽", 2); AddFriend("辦公室主任", 3); AddFriend("經理辦", 4);
                AddFriend("黨委辦", 17); AddFriend("宣傳辦", 16); AddFriend("退休辦", 15); break;
            case "MyStranger":
                AddFriend("賭友", 16); AddFriend("牌友", 14); AddFriend("聊友", 15);
                AddFriend("吹友", 12); AddFriend("侃友", 11); AddFriend("驢友", 9);
                AddFriend("書友", 10); AddFriend("筆友", 13); break;
        }
    }

    private void AddFriend(string name, int imageIndex)
    {
        listView.Items.Add(new ListViewItem(name, imageIndex));
    }
}

關鍵技術細節解析

技術點說明
Dock 填滿順序先設 None 重置,再依序設定按鈕 Dock,最後 listView.Dock = Fill 佔據剩餘空間
Z-order 控制SendToBack() 將按鈕送到底層,BringToFront() 將 ListView 置頂
LargeImageListListView.View = LargeIcon 時,ImageList 提供 32x32 頭像
Clear() vs Items.Clear()Clear() 同時清除項目與欄位,Items.Clear() 僅清項目

常見問題與解決

  • 閃爍:設定 this.DoubleBuffered = true 或覆寫 CreateParams 啟用 WS_EX_COMPOSITED
  • Dock 衝突:同一容器內多個控制項 Dock 相同邊緣時,後設定者會覆蓋前者,需配合 Z-order
  • 高 DPI 模糊:在 Program.cs 加入 Application.SetHighDpiMode(HighDpiMode.PerMonitorV2)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved