Custom Numericupdown

时间:2015-06-15 15:19:11

标签: c# winforms custom-controls

I'm trying to create a custom numericUpDown control. I'm trying to add text to the numericUpDown and I got it working good. But, now I want to find a way to select only the number when clicking in the control, because at this moment when I "edit" the value manually, I can erase the unit I added into the control. I found this control in a software on google that is like a "ranged" numericUpDown. It works like the way I need, it has been possible to click and select only the numbers. When you click in the text, it should select the number to be edited and not the text:

If you click on "to" it selects the 50 that changes when you click in the "arrows"

This is what I have now:

public class RangedNumericUpDown : NumericUpDown
    {
        public int ValueMin = 0;
        public int ValueMax = 10;

        public RangedNumericUpDown()
        {

        }

        protected override void UpdateEditText()
        {
            if(this.Text != this.ValueMin + " to " + this.ValueMax)
                this.Text = this.ValueMin + " to " + this.ValueMax;
        }
    }

I couldn't find any custom control for windows forms like this, and I guess it is possible to create something like that image.

1 个答案:

答案 0 :(得分:2)

嗯,你没有足够的代码。不太确定我推荐这个,移动"焦点"从一个值到另一个值并不是非常直观的。只需使用两个NUD,您就可以获得更好的UI。

Anyhoo,一些可以使用的代码:

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Globalization;

class RangeUpDown : NumericUpDown {
    public decimal LowValue { get; set; }
    public decimal HighValue { get; set; }

    private bool lowFocused = true;
    private const string separator = " to ";

    protected override void UpdateEditText() {
        if (base.UserEdit) ParseText();
        var lotext = FormatValue(LowValue);
        var hitext = FormatValue(HighValue);
        this.Text = lotext + separator + hitext;
        if (lowFocused) {
            EditBox.SelectionStart = 0;
            EditBox.SelectionLength = lotext.Length;
        }
        else {
            EditBox.SelectionStart = lotext.Length + separator.Length;
            EditBox.SelectionLength = hitext.Length;
        }
        EditBox.Focus();
    }

    public override void UpButton() {
        if (base.UserEdit) ParseText();
        if (IsLowValueFocused()) {
            LowValue = Math.Min(this.Maximum, LowValue + this.Increment);
            if (HighValue < LowValue) HighValue = LowValue;
        }
        else {
            HighValue = Math.Min(this.Maximum, HighValue + this.Increment);
        }
        this.OnValueChanged(EventArgs.Empty);
        UpdateEditText();
    }

    public override void DownButton() {
        if (base.UserEdit) ParseText();
        if (IsLowValueFocused()) {
            LowValue = Math.Max(this.Minimum, LowValue - this.Increment);
        }
        else {
            HighValue = Math.Max(this.Minimum, HighValue - this.Increment);
            if (LowValue > HighValue) LowValue = HighValue;
        }
        this.OnValueChanged(EventArgs.Empty);
        UpdateEditText();
    }

    private bool IsLowValueFocused() {
        lowFocused = EditBox.Text.Substring(EditBox.SelectionStart).Contains(separator.Trim());
        return lowFocused;
    }

    private string FormatValue(decimal value) {
        var fmt = (this.ThousandsSeparator ? "N" : "F");
        var frac = this.DecimalPlaces.ToString(CultureInfo.CurrentCulture);
        return value.ToString(fmt + frac, CultureInfo.CurrentCulture);
    }

    private TextBox EditBox { get { return (TextBox)Controls[1]; } }

    private void ParseText() {
        // Not implemented
        base.UserEdit = false;
    }
}