我正在使用.NET 3.5和Windows Forms进行C#项目。我需要设计一个具有多个选项的决策步骤,这些选项需要一些解释性文本。为此,我希望有一组RadioButtons来选择一个选项,然后是一个包含解释的附加Label。
我想保持单选按钮的标签和包含说明文字的标签对齐 - 我在图像中添加了红线来说明这一点。我可能会在第二个标签上调整一些边距或其他设置,但是一旦用户选择不同的主题或更改其他设置,这可能会开始变得怪异。什么是规范(和最强大)的方法呢?
答案 0 :(得分:3)
您的问题归结为两个部分问题:
第一个问题很简单:
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;
}
现在,文本确实将像素完美对齐..:
请注意,我使用表单中的两个原始控件。因此,大部分代码只是存储和恢复我需要操作以进行测量的属性;你可以使用两个假人来保存几行。另请注意,我编写了例程,以便它可以衡量RadioButtons
和Labels
,也可能CheckBoxes
。
值得吗?你决定..!
PS:您也可以将RadioButton
和Label
文字合并为一个..这会产生有趣的副作用,整个文本都可以点击..:
以下是绘制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)
不知道为什么我之前没有想到这一点,但以下方法似乎有效:
关键点似乎是“spacer”最初必须可见 - 否则该列的大小将为0.
这是我在设计师中的测试表格:
要更改布局,我使用了以下Load处理程序:
assemblyIdentity
这是运行时的结果:
答案 4 :(得分:-1)
您可以添加一个与radiobutton具有相同文本的不可见虚拟标签。然后,获取该标签的长度并计算解释标签的正确位置。
labelDummy.Text = radioButton1.Text;
labelExplanation.Left = radioButton1.Right - labelDummy.Width;
然而,这似乎仍然是一些像素关闭,即使我的标签的边距为0,也许一些额外的调整可以解决这个问题。这是一个截图,显示我的意思。标签的背景为绿色,以便能够看到额外的保证金。