簡體   English   中英

如何從原始設計器設置中獲取控件的 position 和大小?

[英]How do I get a control's position and size from the original designer settings?

Windows(取決於字體/縮放/縮放)正在調整我的表單大小。 我想以編程方式找到原始 position 以及表單和控件的大小(在設計器中設置。在運行時,這些大小和位置會隨着表單的創建而變化。

Windows(取決於字體/縮放/縮放)正在調整我的表單大小。

Windows 沒有調整您的表單大小。 您的表單配置為自動縮放。 這由AutoScaleMode 屬性控制。 設計器默認值為System.Windows.Forms.AutoScaleMode.Font (真正的默認值為Inherit )。 WinForm 自動縮放的高級概述可以在文檔Current support for automatic scaling中找到。 一個常見的替代值是System.Windows.Forms.AutoScaleMode.DPI 啟用自動縮放時,使用AutoScaleDimensions的值計算的縮放因子和使用報告給應用程序的 DPI 在運行時評估的值。 AutoScaleDimensions在設計器生成的代碼中設置。

如果應用程序被聲明為可識別 DPI,則使用真正的 DPI 值。 如果它不支持 DPI,則 Windows 會告訴該應用程序它正在以 96 dpi 運行。 報告的 DPI 值也會影響在基於字體的縮放中使用的指標。

我想以編程方式找到原始 position 以及表單和控件的大小(在設計器中設置。在運行時,這些大小和位置會隨着表單的創建而變化。

這可以通過在應用自動縮放之前截取該點來實現。 由於您正在處理自動生成的代碼(Form.designer.cs 文件的 InitializeComponent 方法),因此沒有直接的方法可以做到這一點。 正是在此方法中設置了AutoScaleDimensionsAutoScaleMode

當您創建一個新表單時,此方法如下所示。

private void InitializeComponent()
{
    this.components = new System.ComponentModel.Container();
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(800, 450);
    this.Text = "Form1";
}

請注意, AutoScaleDimensions屬性尚未在方法中聲明; 一旦您對表單進行了一些更改(更改屬性或添加控件)並將新信息寫入文件,它將被添加。 僅當AutoScaleMode設置為 DPI 或 Font 時才會寫入AutoScaleDimensions屬性。

以下是更改表單Size的結果。

private void InitializeComponent()
{
    this.SuspendLayout();
    // 
    // Form1
    // 
    this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(782, 453);
    this.Name = "Form1";
    this.Text = "Form1";
    this.ResumeLayout(false);
}

顯示上述內容的目的是向您展示如何在以下建議的解決方案中獲取設置AutoScaleDimensions屬性的值。

建議的解決方案

在設計器中,將表單的 AutoScaleMode 屬性設置為InheritNone 然后修改表單的構造函數代碼以反映以下內容:

SizeF scalingFactor;
public Form1()
{
    InitializeComponent();

    SuspendLayout();
    AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    AutoScaleDimensions = new System.Drawing.SizeF(8.0F, 16.0F);

    // at this point you can obtain the scaling factor that will
    // be applied on ResumeLayout
    scalingFactor = AutoScaleFactor;

    // store the design-time bounds in the control's Tag property
    RecursivelyRecordBounds(this);
    ResumeLayout(true);
}

還要將此方法添加到表單的代碼中。

private static void RecursivelyRecordBounds(Control c)
{
    c.Tag = c.Bounds;
    foreach (Control cc in c.Controls)
    {
        cc.Tag = cc.Bounds;
        if (cc.Controls.Count > 0)
        {
            RecursivelyRecordBounds(cc);
        }
    }
}

就本示例而言,每個控件的設計時Bounds都存儲在其Tag屬性中。 請注意,設置兩個自動縮放屬性必須包含在 SupendLayout/ResumeLayout 區域中。 此外,在設置AutoScaleMode AutoScaleDimensions也很重要。

另一種解決方案 ( hack ) 是將AutoScaleMode屬性設置為 Font 或 DPI,並依賴於Initialize方法的觀察模式。 在此方法中,表單的Text屬性始終設置在兩個縮放屬性之后。 這允許使用 TextChanged 事件來指示檢索設計時邊界的適當時間。

public Form1()
{
    EventHandler eh = (s,e) => RecursivelyRecordBounds(this);;
    TextChanged += eh;
    InitializeComponent();
    TextChanged -= eh;
}

暫無
暫無

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

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