带单位的NumericUpDown |自定义控件|场填充 [英] NumericUpDown with Unit | Custom control | Field padding

查看:109
本文介绍了带单位的NumericUpDown |自定义控件|场填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个自定义控件,该控件继承了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 控件. UpDownEditTextBox.您可以更改控件及其子级的外观.例如,您可以将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆