NumericUpDown with Unit | 定制控制| 场填充

我试图创建一个inheritanceNumericUpDown以显示可设置单位的自定义控件。

这是(视觉上)到目前为止我得到的:

在此处输入图像描述

我的代码: 看起来有点长,但不是那么做

 class NumericUpDownUnit : NumericUpDown { public event EventHandler ValueChanged; ///  /// Constructor creates a label ///  public NumericUpDownUnit() { this.TextChanged += new EventHandler(TextChanged_Base); this.Maximum = 100000000000000000; this.DecimalPlaces = 5; this.Controls.Add(lblUnit); lblUnit.BringToFront(); UpdateUnit(); } public void TextChanged_Base(object sender, EventArgs e) { if(ValueChanged != null) { this.ValueChanged(sender, e); } } ///  /// My designer property ///  private Label lblUnit = new Label(); [Description("The text to show as the unit.")] public string Unit { get { return this.lblUnit.Text; } set { this.lblUnit.Text = value; UpdateUnit(); } } ///  /// When unit has changed, calculate new label-size ///  public void UpdateUnit() { System.Drawing.Size size = TextRenderer.MeasureText(lblUnit.Text, lblUnit.Font); lblUnit.Padding = new Padding(0, 0, 0, 3); lblUnit.Size = new System.Drawing.Size(size.Width, this.Height); lblUnit.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; lblUnit.BackColor = System.Drawing.Color.Transparent; lblUnit.Location = new System.Drawing.Point(this.Width-lblUnit.Width-17, 0); } ///  /// If text ends with seperator, skip updating text as it would parse without decimal palces ///  protected override void UpdateEditText() { if (!this.Text.EndsWith(".") && !this.Text.EndsWith(",")) Text = Value.ToString("0." + new string('#', DecimalPlaces)); } ///  /// Culture fix ///  protected override void OnKeyPress(KeyPressEventArgs e) { if (e.KeyChar.Equals('.') || e.KeyChar.Equals(',')) { e.KeyChar = System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator.ToCharArray()[0]; } base.OnKeyPress(e); } ///  /// When size changes, call UpdateUnit() to recalculate the lable-size ///  protected override void OnResize(EventArgs e) { UpdateUnit(); base.OnResize(e); } ///  /// Usability | On enter select everything ///  protected override void OnEnter(EventArgs e) { this.Select(0, this.Text.Length); base.OnMouseEnter(e); } ///  /// If, when leaving, text ends with a seperator, cut it out ///  protected override void OnLeave(EventArgs e) { if(this.Text.EndsWith(System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator)) { this.Text = this.Text.Substring(0, this.Text.Length - 1); } base.OnLeave(e); } } 

我的问题:

标签目前正在覆盖盒子的末端。 因此,如果有一个大值(或大小很小),它将被标签覆盖,如下所示:

在此处输入图像描述

我知道当输入的值大于输入框的大小时, NumericUpDown类似于滚动函数。 这是在框的末尾触发的。

是否有可能为盒子内的文本设置填充等内容? 例如,将右侧的填充设置为我的标签大小?

我非常喜欢这个自定义控件,但这最后一件事很烦人。


不幸的是我不知道如何查找现有控件的属性,例如有一个名为UpdateEditText()的方法。 也许有人可以告诉我如何查找这个基本函数/属性。

非常感谢!

NumericUpDown是一个inheritance自UpDownBase复合控件的控件。 它包含一个UpDownEdit和一个UpDownButtons控件。 UpDownEdit是一个TextBox 。 您可以更改控件及其子项的外观。 例如,您可以将Label添加到文本框控件并将其停靠在TextBox的右侧,然后通过发送EM_SETMARGINS消息来设置文本框的文本边距以获得此结果:

在此处输入图像描述

 using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Windows.Forms; public class ExNumericUpDown : NumericUpDown { [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hwnd, int msg, int wParam, int lParam); private const int EM_SETMARGINS = 0xd3; private const int EC_RIGHTMARGIN = 2; private Label label; public ExNumericUpDown() : base() { var textBox = Controls[1]; label = new Label() { Text = "MHz", Dock = DockStyle.Right, AutoSize = true }; textBox.Controls.Add(label); } public string Label { get { return label.Text; } set { label.Text = value; if (IsHandleCreated) SetMargin(); } } protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); SetMargin(); } private void SetMargin() { SendMessage(Controls[1].Handle, EM_SETMARGINS, EC_RIGHTMARGIN, label.Width << 16); } }