[英]How to give padding(all sides) to a value inside NumericUpDown Control in Winforms
我遇到了这个问题,即在 Winforms 的 NumericUpDown 控件中为所有方面提供填充值。
显然以前没有人问过这个问题。
控件的实际外观:( https://i.stack.imgur.com/KIweV.png ) 预期控件的外观:在此处输入图像描述
忽略两个附加图像中的其他差异。 只需要从顶部、底部和左侧填充值; 作为这个问题的一部分。
到目前为止,我只发现有一个 TextAlign 属性可以左对齐或右对齐或居中对齐,但这无助于为控件的顶部和底部边缘提供填充。
下面的代码没有解决我的问题 this.numericUpDown1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
AFAIK,您无法控制 winforms NumericUpDown 控件的高度,因此它的文本属性只允许左、中和右(相对于 label,它有 9 种可能性(TopLeft、MiddleCenter、BottomRight 和很快)。
但是,您可以创建自己的控件来替换内置的 numericUpDown,但这需要大量工作。
也许有人已经完成了这项工作并在某处发布了开源。
NumericUpDown
控件有一个内部UpDownEdit
子控件,派生自用于显示和编辑值的TextBox
控件。 您可以 p/invoke 设置单行TextBox
的左边距和/或右边距。 添加到多行TextBox
的顶部和/或底部边距。
考虑列出的扩展 class,它以TextBoxBase
抽象 class 的派生类型为目标。它将SetInnerMargin
方法添加到这些类型以设置内边距。 请注意,对于单行文本框, Padding
结构的 Top 和 Bottom 属性的值将被忽略。
// TextBox, RichTextBox...etc.
public static class TextBoxBaseExtensions
{
private const int EM_SETRECT = 0xB3;
private const int EM_SETMARGINS = 0xD3;
private const int EC_LEFTMARGIN = 0x1;
private const int EC_RIGHTMARGIN = 0x2;
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left, Top, Right, Bottom;
public RECT(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
public RECT(Rectangle r)
{
Left = r.Left;
Top = r.Top;
Right = r.Right;
Bottom = r.Bottom;
}
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref RECT rect);
public static void SetInnerMargin(this TextBoxBase self, Padding pad)
{
if (self.Multiline)
{
var r = new Rectangle(
pad.Left,
pad.Top,
self.ClientSize.Width - pad.Left - pad.Right,
self.ClientSize.Height - pad.Top - pad.Bottom);
var nr = new RECT(r);
SendMessage(self.Handle, EM_SETRECT, 0, ref nr);
}
else
{
SendMessage(
self.Handle,
EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN,
pad.Right * 0x10000 + pad.Left);
}
}
}
使用示例:
var pad = new Padding(5);
textBox1.SetInnerMargin(pad);
richTextBox1.SetInnerMargin(pad);
(numericUpDown1.Controls[1] as TextBox).SetInnerMargin(pad);
确保在调用此方法之前创建并分配了目标控件的句柄。 或者,订阅他们的HandleCreated
事件来调用它。
此外,您可以创建自定义控件来实现此功能。 例如:
public class NumericUpDownEx : NumericUpDown
{
private Padding inMargin = Padding.Empty;
/// <summary>
/// Gets or sets the inner margins. The Left and Right only.
/// The Top and Bottom margins are ignored.
/// </summary>
[DefaultValue(typeof(Padding), "0, 0, 0, 0")]
public Padding InnerMargin
{
get => inMargin;
set
{
if (inMargin != value)
{
inMargin = value;
SetInnerMargins();
}
}
}
/// <inheritdoc cref="TextBox.TextAlign"/>
new public HorizontalAlignment TextAlign
{
get => base.TextAlign;
set
{
if (base.TextAlign != value)
{
base.TextAlign = value;
SetInnerMargins();
}
}
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
SetInnerMargins();
}
private void SetInnerMargins()
{
if (Controls[1] is TextBox tb)
tb.SetInnerMargin(InnerMargin);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.