Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to create datagridview NumericUpDown column

Tags:

c#

winforms

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.

like image 855
Tikam Sangwani Avatar asked Aug 09 '13 11:08

Tikam Sangwani


2 Answers

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);
    }
}
like image 68
Masahiko Sato Avatar answered Oct 04 '22 04:10

Masahiko Sato


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.

like image 33
dizzy.stackoverflow Avatar answered Oct 04 '22 02:10

dizzy.stackoverflow