簡體   English   中英

根據 TabPages 的數量動態調整 TabControl 和 Form 的寬度

[英]Dynamically resize TabControl and Form width to the number of TabPages

我有一個帶有 TabControl 和 ListView 的 windows 表單。
當我運行應用程序時,我希望 TabControl 的Width增加/減少以顯示所有沒有水平滾動條的 TabPage,並相應地調整 Form 的Width ,以確保 TabControl 和 ListView 可見。

屏幕截圖如下。

在此處輸入圖像描述

要將 TabControl 自動調整為其標頭的大小,您需要計算每個 Header 的文本寬度。如果TabControl.SizeMode設置為Fixed ,則更簡單,因為您可以設置ItemSize.Width和所有標頭將具有相同的寬度。

如果TabControl.SizeMode設置為默認Normal ,則必須測量每個 Header 的文本,為邊框添加1px (如果它是第二個 TabPage,則為2px - 基本控件中的小錯誤)。

在第一種情況下,TabControl 的大小為:

tabControl1.Width = tabControl1.TabPages.Count * (tabControl1.ItemSize.Width + 1);

在第二種情況下,使用TextRenderr.MeasureText測量每個 Header 的文本:

private int MeasureTabPagesWidth(TabControl tc)
{
    if (tc.TabPages.Count == 0) return tc.Width;
    int newWidth = 0;
    int border = tc.TabPages.Count == 2 ? 2 : 1;
    var flags = TextFormatFlags.LeftAndRightPadding;

    using (var g = tc.CreateGraphics()) {
        foreach (TabPage tab in tc.TabPages) {
            newWidth += TextRenderer.MeasureText(g, tab.Text, tc.Font, 
                new Size(int.MaxValue, tc.Font.Height + 4), flags).Width + border;
        }
    }
    return newWidth;
}

設置布局

  • 將 TableLayoutPanel 添加到您的表單,其中包含一行和兩列(即刪除一行)
  • 將 TabControl 添加到左側的 Cell,將 ListBox 添加到另一個 Cell。
  • 將兩個單元格的樣式設置為AutoSize添加控件之后)。
  • 將 TableLayoutPanel 設置為: AutoSize = true , AutoSizeMode = GrowAndShrink
  • 以相同的方式將窗體設置為自動調整大小
  • 設置表單的MinimumSizeMaximumSize 前者通常設置為設計尺寸,后者由您決定; 您可以使用當前的Screen WorkingArea作為參考。
  • 在創建或加載窗體時計算 TabControl 的新寬度(即,在其構造函數或OnLoad()Form.Load ),因此窗體將自動調整為 TableLayoutPanel 的大小,進而自動調整大小到其子控件的大小。

現在您可以在運行時添加或刪除 TabPages,並且表單將自動調整大小為您在TabControl.ControlAddedTabControl.ControlRemoved事件處理程序中計算的寬度(同時檢查添加的控件是否屬於類型TabPage )。

示例

  • MeasureTabPagesWidth()方法如上所示。
  • TableLayoutPanel 被命名為tlp1
  • TabControl 被命名為tabControl1
  • 可視示例中使用的按鈕具有定義其角色的名稱。
public partial class AutoSizeForm : Form
{
    public AutoSizeForm()
    {
        InitializeComponent();
        tabControl1.Width = MeasureTabPagesWidth(tabControl1);
    }

    private void tabControl1_ControlAdded(object sender, ControlEventArgs e)
    {
        // Event notified after the TabPage has been added
        if (e.Control is TabPage) {
            tabControl1.Width = MeasureTabPagesWidth(tabControl1);
        }
    }

    private void tabControl1_ControlRemoved(object sender, ControlEventArgs e)
    {
        if (e.Control is TabPage) {
            // Use deferred execution, since the TabPage is removed after 
            // the event handler method completes.
            BeginInvoke(new Action(()=> tabControl1.Width = MeasureTabPagesWidth(tabControl1)));
        }
    }

    private void btnAddPage_Click(object sender, EventArgs e) 
    {
        tabControl1.TabPages.Add(new TabPage("New TabpPage Text"));
    }

    private void btnRemovePage_Click(object sender, EventArgs e)
    {
        if (tabControl1.TabPages.Count > 0) {
            tabControl1.TabPages.RemoveAt(tabControl1.TabPages.Count - 1);
        }
    }

    private void btnAddCtlToTLP_Click(object sender, EventArgs e)
    {
        tlp1.ColumnCount += 1;
        tlp1.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        var mc = new MonthCalendar();
        tlp1.SetColumn(mc, tlp1.ColumnCount - 1);
        tlp1.Controls.Add(mc);
    }
}

這是它的工作原理
在 Windows 7 中測試,因為這似乎是正在使用的系統

窗體 TabControl 自動調整大小

示例項目
Google Drive 上的示例項目.Net Framework 4.8 - C# 7.3
運行前重建解決方案

此示例的起始表單

從該表單開始,我將在運行時添加 8 個選項卡,計算選項卡中文本的寬度 + 填充大小 x2(選項卡的兩側),然后根據需要調整控件的大小。

   public Form1()
    {
        InitializeComponent();
        //Clear our default tabs.
        tabControl1.TabPages.Clear();
        //Add more tabs than would be visible by default
        for (int i=1;i<=8;i++)
        {
            tabControl1.TabPages.Add("Tab " + i.ToString());
        }
        ResizeTabControl();
        ResizeListViewControl();
        ResizeForm();
    }
    void ResizeTabControl()
    {
        int tabCount = tabControl1.TabCount;

        float length = 0;
        using (Graphics g = CreateGraphics())
        {
            //Iterate through the tabs and get the length of the text.
            for (int i = 0; i <= tabCount - 1; i++)
                length += g.MeasureString(tabControl1.TabPages[i].Text, tabControl1.Font).Width;
        }
        //Resize the tab control where X is the length of all text in the tabs plus padding x 2 x total tabs.
        tabControl1.Size = new Size(Convert.ToInt32(length) + (tabCount * 2 * tabControl1.Padding.X), tabControl1.Width);          
    }
    void ResizeListViewControl()
    {
        //Move listview 10 pixels away from tabcontrol's edge
        listView1.Location = new Point(tabControl1.Location.X + tabControl1.Width + 10, listView1.Location.Y);
    }
    void ResizeForm()
    {
        //Resize form to accomodate changes.
        this.Width = listView1.Location.X + listView1.Width + 20;
    }

一切都說完之后,這就是它的樣子:

並且有 20 個標簽,因為為什么不呢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM