如何使 RadioButton 文本和附加标签保持对齐?

vwe*_*ert 3 .net c# alignment radio-button winforms

我正在使用 .NET 3.5 和 Windows 窗体开发一个 C# 项目。我需要设计一个包含多个选项的决策步骤,需要一些解释性文本。为此,我想要一组单选按钮来选择一个选项,后面跟着一个附加标签,每个标签都包含说明。

例子

我想保持单选按钮的标签和包含解释性文本的标签对齐 - 我在图像中添加了红线来说明这一点。我可能可以调整第二个标签上的一些边距或其他设置,但是一旦用户选择不同的主题或更改一些其他设置,这可能会开始看起来很奇怪。执行此操作的规范(且最可靠)方法是什么?

TaW*_*TaW 5

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

\n\n
    \n
  • 单选按钮(或提前考虑时的复选框)有多大。
  • \n
  • 字形和文本之间的间隙有多大。
  • \n
\n\n

第一个问题很简单:

\n\n
Size  s = RadioButtonRenderer.GetGlyphSize(graphics, \n          System.Windows.Forms.VisualStyles.RadioButtonState.CheckedNormal);\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

第二个问题绝非微不足道。该间隙可能是恒定的,也可能不是恒定的,并且字形的左侧还有另一个间隙!如果我真的想把它做好,我想我会编写一个例程来测量启动时的文本偏移量:

\n\n
public Form1()\n{\n    InitializeComponent();\n\n    int gapRB = getXOffset(radioButton1);\n    int gapLB = getXOffset(label1);\n    label1.Left = radioButton1.Left + gapRB - gapLB;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

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

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

\n\n

在此输入图像描述

\n\n

请注意,我使用了表单中的两个原始控件。因此,大部分代码只是存储和恢复我需要操作的测量属性;您可以使用两个虚拟模型来节省几行。另请注意,我编写了例程,以便它可以测量RadioButtonsLabels,并且可能也可以测量CheckBoxes

\n\n

这值得么?你决定..!

\n\n

PS:您还可以将所有者绘制的文本RadioButtonLabel文本合二为一。这会产生有趣的副作用,即整个文本都是可点击的......:

\n\n

在此输入图像描述

\n\n

这是所有者绘制复选框的快速而肮脏的实现:通过设置AutoSize = false并将真实文本与额外文本一起添加到标签中来准备它,并用例如“\xc2\xa7”分隔。请随意更改此设置,也许可以使用标签控件。

\n\n

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

\n\n

标签包含以下字符串:

\n\n
\n

一朵玫瑰是一朵玫瑰是一朵玫瑰..\xc2\xa7A 玫瑰是一朵玫瑰是一朵玫瑰是一朵玫瑰是/\n 玫瑰是摩西认为他的脚趾是的/不可能是百合花或\n 太妃糖daphi dilli / 它一定是玫瑰,因为它与摩西押韵!

\n
\n\n

对于屏幕截图,我实际上使用了这一行:

\n\n
e.Graphics.DrawString(texts[1].Replace("/ ", "\\n"), ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是Paint事件:

\n\n
private void checkBox1_Paint(object sender, PaintEventArgs e)\n{\n    checkBox1.Text = "";\n    string[] texts =  checkBox1.Tag.ToString().Split(\'\xc2\xa7\');\n\n    Font font1 = new Font(checkBox1.Font, FontStyle.Regular);\n\n    e.Graphics.DrawString(texts[0], checkBox1.Font, Brushes.Black, 25, 3);\n    if (texts.Length > 0)\n    {\n        SizeF s = e.Graphics.MeasureString(texts[1], checkBox1.Font, checkBox1.Width - 25);\n        checkBox1.Height = (int) s.Height + 30;\n        e.Graphics.DrawString(texts[1], font1, Brushes.Black, \n                              new RectangleF(new PointF(25, 25), s));\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n