Windows Forms - customizing NumericUpDown to be nullable

两盒软妹~` 提交于 2019-12-24 11:53:33

问题


I found this custom class that allows NumericUpDown to receive nullable values. I use it in an edit form which can be empty or could be populated with a data from a database from where the need for nullable values comes from.

This is the current code :

public partial class NullableNumericUpDown : NumericUpDown
    {
        public NullableNumericUpDown()
        {
            InitializeComponent();
        }

        public NullableNumericUpDown(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }



        private int? _value;

        [Bindable(true)]
        public new int? Value
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;
                if (value != null)
                {
                    base.Value = (int)value;
                    Text = Value.ToString();
                }
                else
                {
                    Text = "";
                }
            }
        }

        private void NullableNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            _value = (int)base.Value;
        }



        void NullableNumericUpDown_TextChanged(object sender, System.EventArgs e)
        {
            if (Text == "")
            {
                _value = null;
            }
        }
    }

I'm fairly new to C# so I can't say I fully understand the code but however the problem that I have is when I populate the Form with data from the database and exactly when the NullableNumericUpDown has some value, let's say - 3. When I change this value to say 5, the final result when I collect the data from the filed in the form is 53. Also if I delete 3 and then hit the incrementing arrow I get 4. It seems that that the initial data is saved throughout the life cycle of the this control, I tried to set 0 at some current places I thought it might help, but it wouldn't and besides the fact that I need to get rid of this initial value if the value of the control is changed in fact it's not enough to just make it 0 cause if I have empty control this must be ok and record it as null instead 0.

Just to be complete here is how I set the data for the NullableNumericUpDown control :

numUpDnAreas.Value = entity.AreasCnt;

this happens on my form_load event. And when I click Save button I collect the data with this :

entity.AreasCnt = numUpDnAreas.Value;

Can this code be refactored to match my needs or should I leave it and just use something like MaskedTextBox or other?


回答1:


Could you try to use UpDown controls from Extended WPF toolkit. http://wpftoolkit.codeplex.com/wikipage?title=DecimalUpDown&referringTitle=Home It may solve your problem and is opensource.

We've had the similiar requirements in our project and we ended up writing our own by creating a custom control wrapping a textbox and setting Binding. AllowNullValue to string.empty




回答2:


There is working example:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NumericUpDownNullableProj
{
    /// <summary>
    /// Represents a Windows spin box (also known as an up-down control) that displays numeric values.
    /// </summary>
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [ComVisible(true)]
    [DefaultBindingProperty("Value")]
    [DefaultEvent("ValueChanged")]
    [DefaultProperty("Value")]
    //[SRDescriptionAttribute("DescriptionNumericUpDown")]
    public class NumericUpDownNullable : NumericUpDown
    {
        public NumericUpDownNullable() : base()
        {
            Text = "";

            ValueChanged += NumericUpDownNullable_ValueChanged;
            TextChanged += NumericUpDownNullable_TextChanged;
        }

        public NumericUpDownNullable(IContainer container) : this()
        {
            container.Add(this);
        }

        private void NumericUpDownNullable_TextChanged(object sender, EventArgs e)
        {
            if (Text == "")
            {
                Value = null;
            }
        }

        private void NumericUpDownNullable_ValueChanged(object sender, EventArgs e)
        {
            if (Value != base.Value)
            {
                Value = base.Value;
            }
        }

        private decimal? _value;
        /// <summary>
        /// Gets or sets the value assigned to the spin box (also known as an up-down control).
        /// 
        /// Returns:
        ///      The numeric value of the System.Windows.Forms.NumericUpDown control.
        /// Exceptions:
        ///    T:System.ArgumentOutOfRangeException:
        ///       The assigned value is less than the System.Windows.Forms.NumericUpDown.Minimum
        ///       property value.-or- The assigned value is greater than the System.Windows.Forms.NumericUpDown.Maximum property value.
        /// </summary>
        [Bindable(true)]
        public new decimal? Value
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;

                if (base.Value != value.GetValueOrDefault())
                {
                    base.Value = value.GetValueOrDefault();
                }

                Text = value?.ToString();
            }
        }
    }
}


来源:https://stackoverflow.com/questions/15406322/windows-forms-customizing-numericupdown-to-be-nullable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!