首页 文章

DataGridView单元格中的自定义控件

提问于
浏览
2

我在DataGridView单元格中有一个自定义控件 . 它是一个包含复选框项(CheckBoxComboBox)的组合框 . 这是问题:1 . 输入一个CheckBoxComboBox并选择一些复选框项 . CheckboxComboBox的文本是已检查项目的csv字符串 . 2.单击另一个emtpy的CheckboxComboBox单元格(没有选中的项目)

结果:新单元格的文本包含旧单元格的文本 . 如果我单击CheckBoxComboBox单元格,然后单击一个非CheckBoxComboBox单元格,然后单击CheckBoxComboBox单元格,它可以正常工作 .

我已经阅读并实现了基于此文档的自定义DataGridViewCell:How to: Host Controls in Windows Forms DataGridView Cells

当我通过自定义DataGridViewEditingControl进行调试时,似乎没有更新EditingControl.Tag .

所以我假设我有一个问题,EditControl正在被重用 .

我尝试过的事情:

1. Override DataGridViewCell.Clone()

public override object Clone()
    {
        DataGridViewCheckBoxComboBoxCell checkBoxComboBoxCell = base.Clone() as DataGridViewCheckBoxComboBoxCell;
        if (checkBoxComboBoxCell != null)
        {
            checkBoxComboBoxCell.Tag = this.Tag;
            checkBoxComboBoxCell.Values = this.Values;


        }
        return checkBoxComboBoxCell; 
    }

2. Override DataGridViewCell.DetachEditingControl()

public override void DetachEditingControl()
    {
        DataGridView dataGridView = this.DataGridView;

        if (dataGridView == null || dataGridView.EditingControl == null)
        {
            throw new InvalidOperationException("Cell is detached or its grid has no editing control.");
        }

        DataGridViewCheckBoxComboBoxCellEditingControl ctl = DataGridView.EditingControl as DataGridViewCheckBoxComboBoxCellEditingControl;
        if (ctl != null)
        {
            //Just trying different things
            ctl.EditingControlFormattedValue = String.Empty;
            ctl.Text = string.Empty;
            ctl.Tag = null;
            ctl.Items.Clear();
        }

        base.DetachEditingControl();
    }

知道如何解决这个问题吗?谢谢 .

EDIT 1

这是DataGridViewCheckBoxComboBoxColumn类

class DataGridViewCheckBoxComboBoxColumn : DataGridViewColumn
{
     public override object Clone()
    {
        DataGridViewCheckBoxComboBoxColumn that = (DataGridViewCheckBoxComboBoxColumn)base.Clone();

        return that;
    }

    private DataGridViewCheckBoxComboBoxCell _cell = null;
    public DataGridViewCheckBoxComboBoxColumn()
    {
        _cell = new DataGridViewCheckBoxComboBoxCell();
        base.CellTemplate = _cell;
    }

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

    public string Values
    {
        set
        {
            _cell.Tag = value;
            this.Tag = value;
        }
        get
        {
            return _cell.Tag.ToString();
        }
    }
}

EDIT 2 我的DataGridViewCheckBoxComboBoxCell重写了Paint() . 当我在这个方法上放置一个断点时,单击该单元格时会调用它两次 . 第一次调用时,formattedValue为空 . 但是,第二次,formattedValue包含前一个checkboxcombobox单元格的错误字符串 .

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

为什么它被调用两次,为什么在第二次调用时它是否包含正确单元格的错误格式化值?

1 回答

  • 1

    弄清楚了 . 问题是在DetachEditingControl()中我需要清除CheckBoxItems .

    public override void DetachEditingControl()
        {
            DataGridView dataGridView = this.DataGridView;
    
            if (dataGridView == null || dataGridView.EditingControl == null)
            {
                throw new InvalidOperationException("Cell is detached or its grid has no editing control.");
            }
    
            DataGridViewCheckBoxComboBoxCellEditingControl ctl = DataGridView.EditingControl as DataGridViewCheckBoxComboBoxCellEditingControl;
            if (ctl != null)
            {
                ctl.CheckBoxItems.Clear();  //Forgot to do this.
                ctl.EditingControlFormattedValue = String.Empty;
            }
    
            base.DetachEditingControl();
        }
    

相关问题