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

我想保持单选按钮的标签和包含解释性文本的标签对齐 - 我在图像中添加了红线来说明这一点。我可能可以调整第二个标签上的一些边距或其他设置,但是一旦用户选择不同的主题或更改一些其他设置,这可能会开始看起来很奇怪。执行此操作的规范(且最可靠)方法是什么?
您的问题归结为两个部分问题:
\n\n第一个问题很简单:
\n\nSize s = RadioButtonRenderer.GetGlyphSize(graphics, \n System.Windows.Forms.VisualStyles.RadioButtonState.CheckedNormal);\nRun Code Online (Sandbox Code Playgroud)\n\n..使用合适的 Graphics 对象。请注意,我使用 RadioButtonState CheckedNormal 因为我不希望在选中或取消选中按钮时标签以不同的方式对齐。
\n\n第二个问题绝非微不足道。该间隙可能是恒定的,也可能不是恒定的,并且字形的左侧还有另一个间隙!如果我真的想把它做好,我想我会编写一个例程来测量启动时的文本偏移量:
\n\npublic Form1()\n{\n InitializeComponent();\n\n int gapRB = getXOffset(radioButton1);\n int gapLB = getXOffset(label1);\n label1.Left = radioButton1.Left + gapRB - gapLB;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这是测量功能。请注意,它甚至不使用字形测量。另请注意,仅测量 RadioButton 的文本偏移量是不够的。您还需要测量标签的偏移!
\n\nint 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}\nRun Code Online (Sandbox Code Playgroud)\n\n现在文本确实像素完美对齐......:
\n\n
请注意,我使用了表单中的两个原始控件。因此,大部分代码只是存储和恢复我需要操作的测量属性;您可以使用两个虚拟模型来节省几行。另请注意,我编写了例程,以便它可以测量RadioButtons和Labels,并且可能也可以测量CheckBoxes。
这值得么?你决定..!
\n\nPS:您还可以将所有者绘制的文本RadioButton与Label文本合二为一。这会产生有趣的副作用,即整个文本都是可点击的......:

这是所有者绘制复选框的快速而肮脏的实现:通过设置AutoSize = false并将真实文本与额外文本一起添加到标签中来准备它,并用例如“\xc2\xa7”分隔。请随意更改此设置,也许可以使用标签控件。
我清除文本以防止它绘制它,并决定偏移量。要测量它,您可以使用GetGlyphSize上面的方法。请注意 DrawString 方法如何支持嵌入的 \'\\n\' 字符。
标签包含以下字符串:
\n\n\n\n\n一朵玫瑰是一朵玫瑰是一朵玫瑰..\xc2\xa7A 玫瑰是一朵玫瑰是一朵玫瑰是一朵玫瑰是/\n 玫瑰是摩西认为他的脚趾是的/不可能是百合花或\n 太妃糖daphi dilli / 它一定是玫瑰,因为它与摩西押韵!
\n
对于屏幕截图,我实际上使用了这一行:
\n\ne.Graphics.DrawString(texts[1].Replace("/ ", "\\n"), ...\nRun Code Online (Sandbox Code Playgroud)\n\n这是Paint事件:
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}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
2875 次 |
| 最近记录: |