您的问题归结为两个部分问题:
- RadioButton(或提前考虑时的 CheckBox)有多大..
- 字形和文本之间的间隙有多大。
第一个问题很简单:
Size s = RadioButtonRenderer.GetGlyphSize(graphics,
System.Windows.Forms.VisualStyles.RadioButtonState.CheckedNormal);
..使用合适的 Graphics 对象。请注意,我使用 RadioButtonState CheckedNormal 因为我不希望标签在选中或未选中按钮时以不同方式对齐..
第二个绝不是微不足道的。间隙可能是恒定的,也可能不是恒定的,字形左侧还有另一个间隙!如果我真的想把它弄好,我想我会写一个例程来测量启动时的文本偏移:
public Form1()
{
InitializeComponent();
int gapRB = getXOffset(radioButton1);
int gapLB = getXOffset(label1);
label1.Left = radioButton1.Left + gapRB - gapLB;
}
这里是测量功能。请注意,它甚至不使用字形测量。另请注意,仅测量 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;
}
现在文本确实对齐像素完美..:
请注意,我使用表单中的两个原始控件。因此,大部分代码只是存储和恢复我需要为测量操作的属性;你可以通过使用两个假人来节省几行。另外请注意,我编写了例程,以便它可以测量RadioButtons 和Labels,可能还有CheckBoxes。..
值得吗?你决定..!
PS:您还可以将RadioButton 和Label 文本合并为一个所有者。这会产生有趣的副作用,整个文本都可以点击。..:
这是所有者绘制 CheckBox 的快速而肮脏的实现:通过设置 AutoSize = false 并将真实文本与额外文本一起添加到 Tag 中,用例如分隔符分隔来准备它。 “§”。随意更改此设置,可能使用 Label 控件..
我清除文本以防止它绘制它并决定偏移量。要测量它,您可以使用上面的GetGlyphSize。请注意 DrawString 方法如何尊重嵌入的 '\n' 字符。
标签包含这个字符串:
玫瑰是玫瑰是玫瑰..§玫瑰是玫瑰是玫瑰是玫瑰是玫瑰是/
一朵玫瑰是摩西认为他的脚趾是/不可能是百合或
taffy daphi dilli / 它一定是玫瑰,因为它与 mose 押韵!
我在截图中实际上使用了这一行:
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));
}
}