C# 自定义DataGridViewColumn值在失去焦点后消失

C# 自定义DataGridViewColumn值在失去焦点后消失,c#,winforms,custom-controls,datagridviewcolumn,C#,Winforms,Custom Controls,Datagridviewcolumn,我已经在WinForms中为我的项目创建了自定义DataGridViewColumn。控件呈现得非常完美,但一旦我输入值并移动到另一个单元格,该值就会消失,并在我签入CellEndEdit时显示为null 代码如下: class NumericEditControl : NumericTextBox, IDataGridViewEditingControl { DataGridView dataGridView; private bool valueChanged = false

我已经在WinForms中为我的项目创建了自定义DataGridViewColumn。控件呈现得非常完美,但一旦我输入值并移动到另一个单元格,该值就会消失,并在我签入CellEndEdit时显示为null

代码如下:

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; }
    }

}
单元类别如下所示:

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";
        }
    }


}
最后是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;
        }
    }
}
在设计中

private GridControl.NumericDataColumn colRoll;

它呈现控件,但我无法理解值为何消失。你能帮我解决一下吗?

事实证明,我们还必须处理控件的文本/值更改事件,直到单元格变脏为止,除非单元格变脏,否则值将无法保留。因此,我不得不将以下方法添加到我的NumericEditControl类中

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);
        }
    }
}

添加此方法挽救了我的生命,我的控件现在工作正常:D感谢您的输入。

此网格没有数据源。我在弹出式表单中使用这个数据网格来输入值。如果没有数据源,这会不会不起作用?我想,因为我是从TextBoxCell派生的,所以它的行为会是这样的。就像我有一些没有任何数据源的GridView和按钮事件一样,我只是读取datagridview中的值。基本上是人工输入。用户手动输入值,并在单击按钮时保存这些值,以防您需要知道NumericTextBox类只是TextBox对象的派生,它有一个Value属性,返回从TextBox的.Text转换而来的双值。同样在MSDN示例中(我从中获得了引用)他们从DateTimePicker派生控件,DateTimePicker有一个OnValueChanged触发器来检查更改的值。文本框控件中是否有类似的内容?让我们来看看。