[英]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.