问题
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