Click here to Skip to main content
15,891,473 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
>>>Tried to post this before and it seemed to hang. Pardon if this is a double post>>>

I have a DataGridView with three custom column controls. One is for a date picker, the code for which I
found online. I modified that to give me a time-only date picker. I found that someone had taken the same code and modified it to produce a NumericUpDown spin control for DataGridViews. I'm using this custom NumericUpDown control and it works great except for one feature - when the initial value of the data it displays is zero, it will not display the zero. It displays all other initial values, but leaves the cell blank for a zero.

My question is how to get the initial value of zero to display?

Below is the code. Just add it to your project, change the namespace if you wish, and then pick NumericUpDownColumn for ColumnType in any DataGridView column.

I happen to be using an ArrayList of objects as my DataSource to the grid (via a BindingSource), but any data source should exhibit the behavior.

C#
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;

// The original code was copied directly from:
//		http://www.experts-exchange.com/Microsoft/Development/Microsoft_Programming/WPF_and_Silverlight/Q_24582172.html
//
// I modified the format to display integer values instead of decimal, and fixed a few comments (the code had obviously been copied from somewhere else,
// with original comments in place referring to a Calendar class). Other than that, it works as is.

namespace EpiModule
{
	/// <summary>
	/// A spinner (NumericUpDown) class specifically for use in a DataGridView, with a range from 0 - 120.
	/// </summary>
	public class NumericUpDownColumn : DataGridViewColumn
	{ 
		public NumericUpDownColumn() : base(new NumericUpDownCell())
		{
		}

		public NumericUpDownColumn(DataGridViewCell cell)
			: base(cell)
		{
		}

		public override DataGridViewCell CellTemplate
		{
			get { return base.CellTemplate; }
			
			set {
					// Ensure that the cell used for the template is a NumericUpDownCell.
				if ((value != null) && !value.GetType().IsAssignableFrom(typeof(NumericUpDownCell)))
				{
					throw new InvalidCastException("Must be a NumericUpDownCell");
				}
				base.CellTemplate = value;
			}
		}
	}

	/// <summary>
	/// An auxilary class to NumericUpDownColumn that carries out the cell editing.
	/// </summary>
	public class NumericUpDownCell : DataGridViewTextBoxCell
	{
		public NumericUpDownCell()
		{
			this.Style.Format = "#";
		}
		
		public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
		{
			// Set the value of the editing control to the current cell value.
			base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
			NumericUpDownEditingControl ctl = (NumericUpDownEditingControl)DataGridView.EditingControl;
			ctl.Value = Convert.ToDecimal(this.Value);
		}
		
		public override Type EditType
		{
			// Return the type of the editing contol that NumericUpDownCell uses.
			get { return typeof(NumericUpDownEditingControl); }
		}
		
		public override Type ValueType
		{
			// Return the type of the value that NumericUpDownCell contains.
			get { return typeof(int); }
		}
		
		public override object DefaultNewRowValue
		{
			// Default value for a newly added row in the grid
			get { return 0; }
		}
	}

	/// <summary>
	/// An auxilary class to NumericUpDownColumn that supplies the appropriate overridden interfaces to the normal NumericUpDown control.
	/// </summary>
	class NumericUpDownEditingControl : NumericUpDown, IDataGridViewEditingControl
	{
		private DataGridView dataGridViewControl;
		private bool valueIsChanged = false;
		private int rowIndexNum;
		protected bool initializing = false;

		public NumericUpDownEditingControl()
		{
			initializing = true;

			this.Minimum = (decimal)0;
			this.DecimalPlaces = 0;
			this.Maximum = 120;

			initializing = false;
		}
		
		virtual public object EditingControlFormattedValue
		{
			get { return this.Value.ToString("#"); }
			
			set
			{
				if (value is int)
				{
					this.Value = int.Parse(Value.ToString());
				}
				else if (value is decimal)
				{
					this.Value = decimal.Parse(value.ToString());
				}
			}
		}
		
		virtual public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
		{
			return this.Value.ToString("#");
		}
		
		public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
		{
			this.Font = dataGridViewCellStyle.Font;
			this.ForeColor = dataGridViewCellStyle.ForeColor;
			this.BackColor = dataGridViewCellStyle.BackColor;
		}
		
		public int EditingControlRowIndex
		{
			get { return rowIndexNum; }
			set { rowIndexNum = value; }
		}
		
		public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
		{
			// Let the DateTimePicker handle the keys listed.
			switch (key & Keys.KeyCode)
			{
				case Keys.Left:
				case Keys.Up:
				case Keys.Down:
				case Keys.Right:
				case Keys.Home:
				case Keys.End:
				case Keys.PageDown:
				case Keys.PageUp:
				return true;
				default:
					return false;
			}
		}
		
		public void PrepareEditingControlForEdit(bool selectAll)
		{
			// No preparation needs to be done.
		}
		
		public bool RepositionEditingControlOnValueChange
		{
			get { return false; }
		}
		
		public DataGridView EditingControlDataGridView
		{
			get { return dataGridViewControl; }
			set { dataGridViewControl = value; }
		}
		
		public bool EditingControlValueChanged
		{
			get { return valueIsChanged; }
			set { valueIsChanged = value; }
		}
		
		public System.Windows.Forms.Cursor EditingControlCursor
		{
			get { return base.Cursor; }
		}
		
		System.Windows.Forms.Cursor IDataGridViewEditingControl.EditingPanelCursor
		{
			get { return EditingControlCursor; }
		}
		
		protected override void OnValueChanged(EventArgs eventargs)
		{
			if (!initializing) // Original code blew up without this
			{
				// Notify the DataGridView that the contents of the cell have changed.
				valueIsChanged = true;
				this.EditingControlDataGridView.NotifyCurrentCellDirty(true);				base.OnValueChanged(eventargs);
			}
		}
	}
Posted

1 solution

The problem is in formatting

C#
// instead of # you should put 0
return this.Value.ToString("#");


go to this link - it will help you.

Custom Numeric Format Strings[^]
 
Share this answer
 
Comments
Member 9940802 29-Mar-13 10:51am    
Holy smoke! That was the fastest answer I've ever received online. And - it worked!

Thank you so very much.
Member 12246248 28-Jul-19 17:31pm    
RajeshRaushan is the MVP. GOD SEND THANK YOU SO MUCH!!!!!!!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900