首页 > 解决方案 > 如何在锚定到右侧时使用 AutoSize 获取标签以更新其位置?

问题描述

我有一个简单System.Windows.Forms.LabelSystem.Windows.Forms.Form. 我想动态调整标签的大小以适应加载的文本运行时,同时将其锚定在其父表单的右侧和底部。

根据MSDN 文档

从我的阅读来看,我希望第二个事实会覆盖第一个事实,Anchor而不是AnchorStyles.None. 然而,这在实践中似乎并不成立。

考虑以下:

    // From ExampleForm.Designer.cs
    this.label = new System.Drawing.Label();
    this.label.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
    this.label.AutoSize = true;
    this.label.Location = new System.Drawing.Point(600, 400);
    this.label.Size = new System.Drawing.Size(170, 20);
    this.label.Text = "[Populated at Runtime]";
    this.label.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
    // ...
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(800, 450);
    this.Controls.Add(this.label);
    // ...


    // Sometime after Form Initialization, this is called
    void PopulateLabel() {
        var oldRight = label.Right;
        label.Text = "Hey here's some new text. It's pretty long so the control will have to resize";

        // Without this next line, the Right Anchor distance is not maintained.
        // label.Left -= (label.Right - oldRight);
        System.Diagnostics.Debug.Assert(label.Anchor.HasFlag(AnchorStyles.Right) && label.Right == oldRight, "The label didn't stay anchored to the right");
    }

显然,我可以通过手动跟踪距离来解决这个问题,如上所述。我只是想知道是否有某种“应该”工作的方式我做错了。

我必须提供的一个观察是:如果标签没有固定在底部,它就可以工作。

我需要在标签上调用 Suspend/Resume/PerformLayout 吗?在表格上?文档错了吗?我是愚蠢的天真还是完全误解了什么?我是否需要某种中间控制才能使其工作并且文档假设我知道这一点?

为了解决出现在类似问题(或我梦寐以求)中的一些可能的并发症:

标签: c#.netwinforms

解决方案


尝试使用 a TableLayout,它往往会更好地服从Control布局属性。例如:

public class MyForm : Form {

    Label label = new Label() { BackColor = Color.Blue, ForeColor = Color.White };

    public MyForm() {

        TableLayoutPanel panel = new TableLayoutPanel() { BackColor = Color.Green };
        panel.ColumnCount = 1;
        panel.RowCount = 1;
        panel.Controls.Add(label, 0, 0);
        panel.Dock = DockStyle.Bottom;
        panel.AutoSize = true;
        panel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;

        panel.Controls.Add(label);

        //this.label.Anchor = AnchorStyles.Right | AnchorStyles.Top;// | AnchorStyles.Bottom; // ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
        //this.label.Dock = DockStyle.Fill;
        this.label.Dock = DockStyle.Right;
        this.label.AutoSize = true;
        this.label.Margin = Padding.Empty;
        //this.label.Location = new System.Drawing.Point(600, 400);
        //this.label.Size = new System.Drawing.Size(170, 20);
        this.label.Text = "[Populated at Runtime]";
        //this.label.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
        // ...
        //this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        //this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(800, 450);
        //this.Controls.Add(this.label);
        this.Controls.Add(panel);
        // ...

        Button btn = new Button { Text = "Change text" };
        btn.Click += delegate {
            PopulateLabel();
        };
        Controls.Add(btn);
    }

    // Sometime after Form Initialization, this is called
    void PopulateLabel() {
        var oldRight = label.Right;
        label.Text = "Hey here's some new text. It's pretty long so the control will have to resize";

        // Without this next line, the Right Anchor distance is not maintained.
        // label.Left -= (label.Right - oldRight);
        //System.Diagnostics.Debug.Assert(label.Anchor.HasFlag(AnchorStyles.Right) && label.Right == oldRight, "The label didn't stay anchored to the right");
    }

}

推荐阅读