Tikam Sangwani
Tikam Sangwani

Reputation: 325

how to create datagridview NumericUpDown column

I want to add a column in datagridview which is NumericUpDown type. so i have created custom column type for that and it is working fine but this control is visible every time. I just want when i enter in a particular cell of this column(NumericUpdown column) then only this control show. i want as shown in following screenshot. enter image description here

any help will appreciate.

Upvotes: 8

Views: 16375

Answers (3)

Exceptyon
Exceptyon

Reputation: 1582

MSDN sample code: DGV_NUPD.exe

pick the 3 .cs files, add them to your project you are good to go

Related MSDN tutorial: http://msdn.microsoft.com/en-us/library/aa730881(v=vs.80).aspx

Upvotes: 0

Masahiko Sato
Masahiko Sato

Reputation: 81

I modify Web sample including MIN/MAX range.

public class NumericUpDownColumn : DataGridViewColumn
{
    public NumericUpDownColumn()
        : base(new NumericUpDownCell())
    {
    }

    public override DataGridViewCell CellTemplate
    {
        get { return base.CellTemplate; }
        set
        {
            if (value != null && !value.GetType().IsAssignableFrom(typeof(NumericUpDownCell)))
            {
                throw new InvalidCastException("Must be a NumericUpDownCell");
            }
            base.CellTemplate = value;
        }
    }
}

public class NumericUpDownCell : DataGridViewTextBoxCell
{
    private readonly decimal min;
    private readonly decimal max;

    public NumericUpDownCell()
        : base()
    {
        Style.Format = "F0";
    }
    public NumericUpDownCell(decimal min, decimal max)
        : base()
    {
        this.min = min;
        this.max = max;
        Style.Format = "F0";
    }

    public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
        NumericUpDownEditingControl ctl = DataGridView.EditingControl as NumericUpDownEditingControl;
        ctl.Minimum = this.min;
        ctl.Maximum = this.max;
        ctl.Value = Convert.ToDecimal(this.Value);
    }

    public override Type EditType
    {
        get { return typeof(NumericUpDownEditingControl); }
    }

    public override Type ValueType
    {
        get { return typeof(Decimal); }
    }

    public override object DefaultNewRowValue 
    {
        get { return null; } //未編集の新規行に余計な初期値が出ないようにする
    }
}

public class NumericUpDownEditingControl : NumericUpDown, IDataGridViewEditingControl
{
    private DataGridView dataGridViewControl;
    private bool valueIsChanged = false;
    private int rowIndexNum;

    public NumericUpDownEditingControl()
        : base()
    {
        this.DecimalPlaces = 0;
    }

    public DataGridView EditingControlDataGridView
    {
        get { return dataGridViewControl; }
        set { dataGridViewControl = value; }
    }

    public object EditingControlFormattedValue
    {
        get{ return this.Value.ToString("F0"); }
        set{ this.Value = Decimal.Parse(value.ToString()); }
    }
    public int EditingControlRowIndex
    {
        get { return rowIndexNum; }
        set { rowIndexNum = value; }
    }
    public bool EditingControlValueChanged
    {
        get { return valueIsChanged; }
        set { valueIsChanged = value; }
    }

    public Cursor EditingPanelCursor
    {
        get { return base.Cursor; }
    }

    public bool RepositionEditingControlOnValueChange
    {
        get { return false; }
    }

    public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
    {
        this.Font = dataGridViewCellStyle.Font;
        this.ForeColor = dataGridViewCellStyle.ForeColor;
        this.BackColor = dataGridViewCellStyle.BackColor;
    }

    public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
    {
        return (keyData == Keys.Left || keyData == Keys.Right ||
            keyData == Keys.Up || keyData == Keys.Down ||
            keyData == Keys.Home || keyData == Keys.End ||
            keyData == Keys.PageDown || keyData == Keys.PageUp);
    }

    public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
    {
        return this.Value.ToString();
    }

    public void PrepareEditingControlForEdit(bool selectAll)
    {
    }

    protected override void OnValueChanged(EventArgs e)
    {
        valueIsChanged = true;
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnValueChanged(e);
    }
}

Upvotes: 8

blitz_jones
blitz_jones

Reputation: 1078

This might be more of a workaround than a solution, but you could consider writing a simply custom form that displays directly over the cell when you click on the cell. That custom form would give you the numericUpDown behavior you want, and then as soon as you click back anywhere else on the DataGridView the custom form would be hidden, with its value being saved into the cell. Seems like this would be a simple way to handle the issue and get identical behavior. Good luck.

Upvotes: 1

Related Questions