如何保持RadioButton文本和其他标签对齐?

时间:2015-05-21 14:44:26

标签: c# .net winforms radio-button alignment

我正在使用.NET 3.5和Windows Forms进行C#项目。我需要设计一个具有多个选项的决策步骤,这些选项需要一些解释性文本。为此,我希望有一组RadioButtons来选择一个选项,然后是一个包含解释的附加Label。

example

我想保持单选按钮的标签和包含说明文字的标签对齐 - 我在图像中添加了红线来说明这一点。我可能会在第二个标签上调整一些边距或其他设置,但是一旦用户选择不同的主题或更改其他设置,这可能会开始变得怪异。什么是规范(和最强大)的方法呢?

5 个答案:

答案 0 :(得分:3)

您的问题归结为两个部分问题:

  • RadioButton(或提前思考时的CheckBox)有多大.. ..
  • 字形和文字之间的差距有多大。

第一个问题很简单:

Size  s = RadioButtonRenderer.GetGlyphSize(graphics, 
          System.Windows.Forms.VisualStyles.RadioButtonState.CheckedNormal);

..使用合适的Graphics对象。请注意,我使用RadioButtonState CheckedNormal,因为我不希望Lables在选中或取消选中按钮时以不同方式对齐。

第二个不过是微不足道的。间隙可能是也可能不是恒定的,字形左边还有另一个间隙!如果我真的想要做对,我想我会在启动时写一个例程测量文本偏移量:

public Form1()
{
    InitializeComponent();

    int gapRB = getXOffset(radioButton1);
    int gapLB = getXOffset(label1);
    label1.Left = radioButton1.Left + gapRB - gapLB;
}

这是测量功能。请注意,甚至不使用Glyph测量。另请注意,仅测量RadioButton的文本偏移量是不够的。您还需要测量Label的偏移量!

int getXOffset(Control ctl)
{
    int offset = -1;
    string save = ctl.Text; Color saveC = ctl.ForeColor; Size saveSize = ctl.Size;
    ContentAlignment saveCA = ContentAlignment.MiddleLeft;
    if  (ctl is Label)
    {
        saveCA = ((Label)ctl).TextAlign;
        ((Label)ctl).TextAlign = ContentAlignment.BottomLeft;
    }

    using (Bitmap bmp = new Bitmap(ctl.ClientSize.Width, ctl.ClientSize.Height))
    using (Graphics G = ctl.CreateGraphics() )
    {
        ctl.Text = "_";
        ctl.ForeColor = Color.Red;
        ctl.DrawToBitmap(bmp, ctl.ClientRectangle);
        int x = 0; 
        while (offset < 0 && x < bmp.Width - 1)
        {
            for (int y = bmp.Height-1; y > bmp.Height / 2; y--)
            {
                Color c = bmp.GetPixel(x, y);
                if (c.R > 128 && c.G == 0)     { offset = x; break; }
            }
            x++;
        }
    }
    ctl.Text = save;  ctl.ForeColor = saveC;   ctl.Size = saveSize;
    if (ctl is Label)  { ((Label)ctl).TextAlign =  saveCA;   }

    return offset;
}

现在,文本确实将像素完美对齐..:

enter image description here

请注意,我使用表单中的两个原始控件。因此,大部分代码只是存储和恢复我需要操作以进行测量的属性;你可以使用两个假人来保存几行。另请注意,我编写了例程,以便它可以衡量RadioButtonsLabels,也可能CheckBoxes

值得吗?你决定..!

PS:您也可以将RadioButtonLabel文字合并为一个..这会产生有趣的副作用,整个文本都可以点击..:

enter image description here

以下是绘制CheckBox的所有者的快速而肮脏的实现:通过设置AutoSize = false并将实际文本与额外文本一起添加到标记中来准备它,由标记分隔。 “§”。您可以随意更改此设置,也许可以使用Label控件..

我清除文本以防止它绘制它并且我决定偏移。要测量它,可以使用上面的GetGlyphSize。注意DrawString方法如何表示嵌入的'\ n'字符。

标签包含此字符串:

  玫瑰玫瑰是玫瑰玫瑰玫瑰玫瑰是玫瑰玫瑰是玫瑰   玫瑰是摩西认为他的脚趾是/不能是百合花   taffy daphi dilli /它必须是一朵玫瑰,因为它与摩西押韵!

我在屏幕截图中实际使用了这一行:

e.Graphics.DrawString(texts[1].Replace("/ ", "\n"), ...

以下是Paint事件:

private void checkBox1_Paint(object sender, PaintEventArgs e)
{
    checkBox1.Text = "";
    string[] texts =  checkBox1.Tag.ToString().Split('§');

    Font font1 = new Font(checkBox1.Font, FontStyle.Regular);

    e.Graphics.DrawString(texts[0], checkBox1.Font, Brushes.Black, 25, 3);
    if (texts.Length > 0)
    {
        SizeF s = e.Graphics.MeasureString(texts[1], checkBox1.Font, checkBox1.Width - 25);
        checkBox1.Height = (int) s.Height + 30;
        e.Graphics.DrawString(texts[1], font1, Brushes.Black, 
                              new RectangleF(new PointF(25, 25), s));
    }
}

答案 1 :(得分:2)

最简单的开箱即用解决方案(在我看来)将使用3个控件而不是2个:一个单选按钮(文本设置为&#34;&#34;),一个标签(在单选按钮旁边)和另一个标签(在它们下面)。这样可以让您更轻松地在设计器中进行配置,但(更重要的是)更简单的运行时评估和调整(如果需要),以便在样式发生变化时保持对齐。

我确实理解这会消除点击标签以选择单选按钮的好处,但如果您需要,可以在标签的Click事件中添加该行为。

或者,您可以创建一个包含无文本单选按钮和标签的UserControl,并在显示标签的位置时处理UserControl内的行为。

答案 2 :(得分:1)

如果您不关心radiobutton的文本是否为粗体,您可以将其标签设置为多行字符串,并将CheckAlign设置为TopLeft:

radioButton2.CheckAlign = ContentAlignment.TopLeft;
radioButton2.Text = @"Radiobutton

Explanation text";

答案 3 :(得分:1)

不知道为什么我之前没有想到这一点,但以下方法似乎有效:

  1. 使用TableLayoutPanel,其中有两列设置为自动调整其宽度。
  2. 将所有RadioButton放在第一列中,并将它们设置为跨越两列。
  3. 将所有标签放在第二列中,将所有边距设置为0.
  4. 在布局末尾的附加行中添加一个禁用但可见(!)“spacer”RadioButton,不带文字。
  5. 显示表单时,将第一列转换为固定大小并隐藏“spacer”。
  6. 关键点似乎是“spacer”最初必须可见 - 否则该列的大小将为0.

    这是我在设计师中的测试表格:

    design view

    要更改布局,我使用了以下Load处理程序:

    assemblyIdentity

    这是运行时的结果:

    runtime view

答案 4 :(得分:-1)

您可以添加一个与radiobutton具有相同文本的不可见虚拟标签。然后,获取该标签的长度并计算解释标签的正确位置。

labelDummy.Text = radioButton1.Text;
labelExplanation.Left = radioButton1.Right - labelDummy.Width;

然而,这似乎仍然是一些像素关闭,即使我的标签的边距为0,也许一些额外的调整可以解决这个问题。这是一个截图,显示我的意思。标签的背景为绿色,以便能够看到额外的保证金。

Radio button alignment