Custom DataGridViewColumn value disappears after l

2019-05-14 11:03发布

I have created a custom DataGridViewColumn for my project in WinForms. The control renders perfectly, but once I input the value and move to another cell, the value disappears and comes up as null when I check in CellEndEdit.

Following is the code:

class NumericEditControl : NumericTextBox, IDataGridViewEditingControl
{
    DataGridView dataGridView;
    private bool valueChanged = false;
    int rowIndex;

    public NumericEditControl()
    {
        this.Value = 0;
    }

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

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

    public object EditingControlFormattedValue
    {
        get
        {
            return this.Value;
        }
        set
        {
            this.Value = Convert.ToDouble(value);
        }
    }

    public int EditingControlRowIndex
    {
        get
        {
            return rowIndex;
        }
        set
        {
            rowIndex = value;
        }
    }

    public bool EditingControlValueChanged
    {
        get
        {
            return valueChanged;
        }
        set
        {
            valueChanged = value;
        }
    }

    public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
    {
        switch (keyData & 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 !dataGridViewWantsInputKey;
        }
    }

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

    public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
    {
        return EditingControlFormattedValue;
    }

    public void PrepareEditingControlForEdit(bool selectAll)
    {

    }

    public bool RepositionEditingControlOnValueChange
    {
        get { return false; }
    }

}

The cell class is as follows:

public class NumericCell : DataGridViewTextBoxCell
{
    public NumericCell()
        : base()
    {
        this.Style.Format = "0";
    }

    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);
        NumericEditControl ctl =
            DataGridView.EditingControl as NumericEditControl;
        // Use the default row value when Value property is null.
        if (this.Value == null)
        {
            ctl.Value = 0;
        }
        else
        {
            ctl.Value = (double)this.Value;
        }
    }

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

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

    public override object DefaultNewRowValue
    {
        get
        {
            return "0";
        }
    }


}

And finally the DataGridViewColumn

public class NumericDataColumn : DataGridViewColumn
{
    public NumericDataColumn()
        : base(new NumericCell())
    {
    }

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

In the designer

private GridControl.NumericDataColumn colRoll;

It renders the control but I cannot understand why the value is disappearing. Can you please help me out

1条回答
我欲成王,谁敢阻挡
2楼-- · 2019-05-14 11:26

It turns out that we have to handle the control's Text / Value change event as well and until and unless the cell is dirty the value will not retain. So I had to add the following method to my NumericEditControl class

class NumericEditControl : NumericTextBox, IDataGridViewEditingControl
{
    //Old code here
    protected override void OnTextChanged(EventArgs e)
    {
        if (dataGridView != null)
        {
            valueChanged = true;

            this.dataGridView.NotifyCurrentCellDirty(true);
            base.OnTextChanged(e);
        }
    }
}

Adding this method saved my life and my control is working properly now :D thanks for the input.

查看更多
登录 后发表回答