自定义DataGridView单元格在单元格离开时变为空白

时间:2012-08-25 13:38:15

标签: c# .net datagridview cell

我在单元格离开时遇到自定义datagridview单元格的问题:单元格变为空白。

我有一个DataGridView,它有一些列。其中一些是标准列(datagridviewtextboxcolumn,datagridviewCheckBoxcolumn),其他是自定义的(我托管了一个自定义控件)。

想象一下以下情况:我更改自定义单元格的值,然后单击另一个标准单元格(p.e.datagridviewTextBoxcolumn)。因此,我进入标准单元格的编辑模式,但自定义单元格值变为空白。为什么?我的自定义单元格是一个图像,后跟一个文本。

更新:在整个演示中,使用datagridview中托管的自定义单元格。这是一个非常小的例子。注意PropertyEditor和PropertyEditorSource是NI的组件(NI Measurement Studio 8.6包)。也许在这里实施的是坏事?这是原因吗?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NationalInstruments.UI.WindowsForms;
using NationalInstruments.UI;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
    InitializeComponent();

    this.dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;

    // Creates a property editor for plot object whose property is LineStep            
    PropertyEditorSource propertyEditorSource = new PropertyEditorSource(new ScatterPlot(), "LineStep");
    propertyEditorSource.Value = LineStep.XYStep;

    PropertyEditor propertyEditor = new PropertyEditor();
    propertyEditor.Source = propertyEditorSource;
    //propertyEditor.SourceValue = LineStep.XYStep; // Default value for property LineStep

    PropertyEditorColumn col = new PropertyEditorColumn(propertyEditor);
    this.dataGridView1.Columns.Add(col);

    // Creates a property editor for xycursor object whose property is Color
    XYCursor xycursor = new XYCursor();
    PropertyEditorSource propertyEditorSource2 = new PropertyEditorSource(xycursor, "Color");
    propertyEditorSource2.Value = Color.Blue;

    PropertyEditor propertyEditor2 = new PropertyEditor();
    propertyEditor2.Source = propertyEditorSource2;

    PropertyEditorColumn col2 = new PropertyEditorColumn(propertyEditor2);
    this.dataGridView1.Columns.Add(col2);     

    this.dataGridView1.DataError +=new  
       DataGridViewDataErrorEventHandler(dataGridView1_DataError);       
}

private void dataGridView1_DataError(Object sender,
    DataGridViewDataErrorEventArgs e)
{
    // Prevents crashing on focus lost
    e.Cancel = false;
}

public class PropertyEditorColumn : DataGridViewColumn
{            
    #region "Necessary for design time adding columns"

    private PropertyEditorSource propertyEditorSource = PropertyEditorSource.Empty;


    public PropertyEditorSource PropertyEditorObject{
        get { return this.propertyEditorSource; }
        set { this.propertyEditorSource = value; }
    }            

    public PropertyEditorColumn() : base(new PropertyEditorCell())
    {
    }

    #endregion             

    public PropertyEditorColumn(PropertyEditor propertyEditor)
        : base(new PropertyEditorCell(propertyEditor))
    {                
    }

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

public class PropertyEditorCell : DataGridViewTextBoxCell
{
    #region "Design Time"

    private PropertyEditorSource propertyEditorSource = PropertyEditorSource.Empty;


    public PropertyEditorSource PropertyEditorObject2
    {
        get { return this.propertyEditorSource; }
        set { this.propertyEditorSource = value; }
    }

    #endregion

    public PropertyEditor propertyEditor = null;

    public PropertyEditorCell() : base()
    {                
    }

    public PropertyEditorCell(PropertyEditor propertyEditor)
        : this()
    {                
        this.propertyEditor = propertyEditor;                
    }

    protected override void Paint(
        Graphics graphics,
        Rectangle clipBounds,
        Rectangle cellBounds,
        int rowIndex,
        DataGridViewElementStates cellState,
        object value,
        object formattedValue,
        string errorText,
        DataGridViewCellStyle cellStyle,
        DataGridViewAdvancedBorderStyle advancedBorderStyle,
        DataGridViewPaintParts paintParts)
    {
        // Call the base class method to paint the default cell appearance.
        base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
            value, formattedValue, errorText, cellStyle,
            advancedBorderStyle, paintParts);
    }

    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);
        PropertyEditorEditingControl ctl = DataGridView.EditingControl as PropertyEditorEditingControl;

        // Use the default row value when Value property is null.
        PropertyEditorSource propertyEditorSource = (PropertyEditorSource)this.Value;                
        if (propertyEditorSource == null)
        {
            ctl.Source = (PropertyEditorSource)this.DefaultNewRowValue;
        }
        else
        {
            ctl.Source = propertyEditorSource;
        }
    }

    public override object Clone() 
    { 
        PropertyEditorCell newCell = (PropertyEditorCell)base.Clone();
        newCell.propertyEditor = this.propertyEditor;

        return newCell; 
    } 

    public override Type EditType
    {
        get
        {
            // Return the type of the editing control that PropertyEditorCell uses.
            return typeof(PropertyEditorEditingControl);
        }
    }

    public override Type ValueType
    {
        get
        {
            // Return the type of the value that PropertyEditorCell contains.
            return typeof(PropertyEditor);                    
        }
    }

    public override object DefaultNewRowValue
    {
        get
        {
            // Use the current default value.                   
            if (this.propertyEditor == null)
            {
                // Design time
                return this.propertyEditorSource;
            }
            else                     
            {
                return this.propertyEditor.Source;
            }                                         
        }
    }
}

class PropertyEditorEditingControl : PropertyEditor, IDataGridViewEditingControl
{
    DataGridView dataGridView;
    private bool valueChanged = false;
    int rowIndex;

    private void EditingControlDataGridView_DataError(Object sender,
        DataGridViewDataErrorEventArgs e)
    {

    }

    public PropertyEditorEditingControl()
    {
    }

    // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
    // property.
    public object EditingControlFormattedValue
    {
        get
        {
            return this.Source;
        }

        set
        {
            if (value is PropertyEditorSource)
            {
                try
                {
                    // This will throw an exception of the string is 
                    // null, empty, or not in the format of a date.
                    this.Source = (PropertyEditorSource)value;
                }
                catch
                {
                    // In the case of an exception, just use the 
                    // default value so we're not left with a null
                    // value.
                    this.Source = PropertyEditorSource.Empty;
                }
            }
        }

    }


    // Implements the 
    // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
    public object GetEditingControlFormattedValue(
        DataGridViewDataErrorContexts context)
    {
        return EditingControlFormattedValue;
    }

    // Implements the 
    // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
    public void ApplyCellStyleToEditingControl(
        DataGridViewCellStyle dataGridViewCellStyle)
    {

        this.Font = dataGridViewCellStyle.Font;
        this.ForeColor = dataGridViewCellStyle.ForeColor;
        this.BackColor = dataGridViewCellStyle.BackColor;                 
    }

    // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
    // property.
    public int EditingControlRowIndex
    {
        get
        {
            return rowIndex;
        }

        set
        {
            rowIndex = value;
        }
    }

    // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
    // method.
    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 !dataGridViewWantsInputKey;
        }
    }

    // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
    // method.
    public void PrepareEditingControlForEdit(bool selectAll)
    {
        // No preparation needs to be done.
    }

    // Implements the IDataGridViewEditingControl
    // .RepositionEditingControlOnValueChange property.
    public bool RepositionEditingControlOnValueChange
    {
        get
        {
            return false;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingControlDataGridView property.
    public DataGridView EditingControlDataGridView
    {
        get
        {
            return dataGridView;
        }
        set
        {
            dataGridView = value;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingControlValueChanged property.
    public bool EditingControlValueChanged
    {
        get
        {
            return valueChanged;
        }
        set
        {
            valueChanged = value;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingPanelCursor property.
    public System.Windows.Forms.Cursor EditingPanelCursor
    {
        get
        {
            return base.Cursor;
        }
    }

    protected override void OnValidated(EventArgs e)
    {
        base.OnValidated(e);
    }

    protected override void OnSourceValueChanged(EventArgs e)
    {
        // Notify the DataGridView that the contents of the cell
        // have changed.
        valueChanged = true;

        // below line cause app crash when focus lost so handled in dataerror event
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnSourceValueChanged(e);
    }
}
}
}

0 个答案:

没有答案