带单位的NumericUpDown |自定义控件|场填充 [英] NumericUpDown with Unit | Custom control | Field padding
问题描述
我正在尝试创建一个自定义控件,该控件继承了NumericUpDown
以显示可设置的单元.
Im trying to create a custom control that inherits NumericUpDown
to show a settable unit.
(从视觉上)这是到目前为止我得到的:
我的代码: 看起来有点长,但没做那么多
class NumericUpDownUnit : NumericUpDown
{
public event EventHandler ValueChanged;
/// <summary>
/// Constructor creates a label
/// </summary>
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);
}
}
/// <summary>
/// My designer property
/// </summary>
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();
}
}
/// <summary>
/// When unit has changed, calculate new label-size
/// </summary>
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);
}
/// <summary>
/// If text ends with seperator, skip updating text as it would parse without decimal palces
/// </summary>
protected override void UpdateEditText()
{
if (!this.Text.EndsWith(".") && !this.Text.EndsWith(","))
Text = Value.ToString("0." + new string('#', DecimalPlaces));
}
/// <summary>
/// Culture fix
/// </summary>
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);
}
/// <summary>
/// When size changes, call UpdateUnit() to recalculate the lable-size
/// </summary>
protected override void OnResize(EventArgs e)
{
UpdateUnit();
base.OnResize(e);
}
/// <summary>
/// Usability | On enter select everything
/// </summary>
protected override void OnEnter(EventArgs e)
{
this.Select(0, this.Text.Length);
base.OnMouseEnter(e);
}
/// <summary>
/// If, when leaving, text ends with a seperator, cut it out
/// </summary>
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);
}
}
我的问题:
该标签目前正盖着盒子的末端.因此,如果输入的值很大(或大小较小),它就会被标签覆盖,如下所示:
The lable is currently covering the end of the box. So if a big value comes in (or the size is low) it gets covered by the label as seen in here:
我知道,当键入的值长于输入框的大小时,NumericUpDown
具有类似滚动功能的功能.这是在框的末尾触发的.
I know that the NumericUpDown
has something like a scroll-function when a typed in value is longer than the size of the inputbox. This is triggered at the end of the box.
是否可以为框内的文本设置诸如 padding 之类的内容?例如将右边的填充设置为我的标签大小?
Is there in any way the possibility of setting up something like padding for the text inside the box? For example setting the padding on the right to the size of my label?
我非常喜欢这个自定义控件,但最后一件事很烦人.
不幸的是,我不知道如何查找现有控件的属性,例如,有一种名为UpdateEditText()
的方法.也许有人可以告诉我如何查找此基本功能/属性.
Unfortunately I dont know how to lookup the properties of an existing control as for example there is a method called UpdateEditText()
. Maybe someone can tell me how to lookup this base functions/properties.
非常感谢!
推荐答案
NumericUpDown
是从 UpDownEdit
和 UpDownEdit
是TextBox
.您可以更改控件及其子级的外观.例如,您可以将Label
添加到文本框控件并将其停靠在TextBox
的右侧,然后通过发送
NumericUpDown
is a control which inherits from UpDownBase
composite control. It contains an UpDownEdit
and an UpDownButtons
control. The UpDownEdit
is a TextBox
. You can change appearance of the control and its children. For example, you can add a Label
to the textbox control and dock it to the right of TextBox
, then set text margins of textbox by sending an EM_SETMARGINS
message to get such result:
代码
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);
}
}
这篇关于带单位的NumericUpDown |自定义控件|场填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!