检测DataGridViewCell

时间:2017-04-06 17:28:55

标签: c# datagridview backcolor

我正在研究一个类,我们称之为MyDataGridView,派生自DataGridView,必须与Excel文件同步(即当DataGridView中的某些内容发生变化时,我需要对Excel文件进​​行相同的更改)。 / p>

要检测DataGridView中的更改,我使用事件(例如,RowsAdded,ColumnRemoved,CellValueChanged等)。但我检测BackColor已更改的单元格时遇到问题。

使用我的班级的其他程序员改变了颜色。为此,他可以使用以下代码:

MyDataGridView myDataGridView;
// create and fill MyDataGridView...
myDataGridView.Rows[0].Cells[0].Style.BackColor = Color.AliceBlue;

我的目标是检测BackColor属性的更改以更改Excel文件。

为实现这一目标,我(未成功)尝试使用多种方法:

  1. CellStyleContentChanged事件(问题:无法从事件处理程序获取Cell本身)。

  2. CellFormatting事件(问题:事件上升了很多次,我无法理解其发生的原因)。

  3. CellStyleChanged事件(问题:仅在Style属性更改时发生事件,但不会发生Style.BackColor事件。)

  4. 覆盖DataGridViewCellStyle类(问题:我不知道如何正确覆盖此类以及是否可以完成此类。)

  5. 有助于重现我的尝试的代码段:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            dataGridView1.CellStyleContentChanged += dataGridView1_CellStyleContentChanged;
            dataGridView1.CellFormatting += dataGridView1_CellFormatting;
        }
    
        // Goal
        private void Form1_Load(object sender, EventArgs e)
        {
            dataGridView1.Columns.Add("column1", "column1");
            dataGridView1.Columns.Add("column2", "column2");
            dataGridView1.Rows.Add("cell1", "cell2");
    
            // how to detect this?
            dataGridView1.Rows[0].Cells[0].Style.BackColor = Color.AliceBlue;
        }
    
        // Attempt #1
        void dataGridView1_CellStyleContentChanged(
            object sender, DataGridViewCellStyleContentChangedEventArgs e)
        {
            // how to get cell itself (rowIndex & columnIndex)?
        }
    
        // Attempt #2
        void dataGridView1_CellStyleChanged(object sender, DataGridViewCellEventArgs e)
        {
            // event only occurs when the Style property changes, but not Style.BackColor
        }
    
        // Attempt #3
        void dataGridView1_CellFormatting(
            object sender, DataGridViewCellFormattingEventArgs e)
        {
            // event rises so many times!
            // and how to get reason of formatting (i need to detect only color change)?
        }
    
        // Attempt #4
        // do i need something like this?
        public class MyDataGridView : DataGridView
        {
            public class MyDataGridViewRowCollection : DataGridViewRowCollection
            {
                public MyDataGridViewRowCollection(DataGridView _dgv) : base(_dgv) { }
    
                public class MyDataGridViewRow : DataGridViewRow
                {
                    public class MyDataGridViewCellCollection : DataGridViewCellCollection
                    {
                        public MyDataGridViewCellCollection(DataGridViewRow _dgvRow) :
                            base(_dgvRow) { }
    
                        public class MyDataGridViewCell : DataGridViewCell
                        {
                            private new MyDataGridViewCellStyle Style { get; set; }
    
                            public class MyDataGridViewCellStyle : DataGridViewCellStyle
                            {
                                public new Color BackColor
                                {
                                    get
                                    {
                                        return base.BackColor;
                                    }
                                    set
                                    {
                                        base.BackColor = value;
    
                                        // TODO: changes in Excel
                                        // ...
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    我会很高兴得到任何建议和答案!

1 个答案:

答案 0 :(得分:0)

与@TaW讨论促使我一次使用多个事件。

我们使用CellStyleContentChanged事件来检测Style.BackColor更改和CellFormatting事件以获取其BackColor已更改的Cell。

此外,我们需要一些Collection来存储更改的颜色,因为这些事件不会按顺序发生(请参阅下面的日志)。

备注!! 此方法仅适用于用户可见的单元格(DataGridView不应包含滚动条)。

public partial class Form1 : Form
{
    string log = "";
    List<Color> changedBackColors = new List<Color>();

    public Form1()
    {
        InitializeComponent();
        this.dataGridView1.CellStyleContentChanged +=
            dataGridView1_CellStyleContentChanged;
        this.dataGridView1.CellFormatting +=
            dataGridView1_CellFormatting;
        this.Shown += Form1_Shown;
    }

    void Form1_Shown(object sender, EventArgs e)
    {
        log += "Change Cell[0,0] (color = blue)\r\n";
        this.dataGridView1.Rows[0].Cells[0].Style.BackColor = Color.Blue;

        log += "Change Cell[0,1] (color = red)\r\n";
        this.dataGridView1.Rows[0].Cells[1].Style.BackColor = Color.Red;
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.dataGridView1.Columns.Add("column1", "column1");
        this.dataGridView1.Columns.Add("column1", "column1");
        this.dataGridView1.Rows.Add("cell1", "cell2");
    }

    private void dataGridView1_CellStyleContentChanged(
        object sender, DataGridViewCellStyleContentChangedEventArgs e)
    {
        log += string.Format(
            "CellStyleContentChanged occurs for Cell[?,?] (color = {0})\r\n",
            e.CellStyle.BackColor.Name);
        this.changedBackColors.Add(e.CellStyle.BackColor);
    }

    private void dataGridView1_CellFormatting(
        object sender, DataGridViewCellFormattingEventArgs e)
    {
        if (this.changedBackColors.Count > 0)
        {
            if (this.changedBackColors.Contains(e.CellStyle.BackColor))
            {
                log += string.Format(
                    "CellFormatting occurs for Cell[{0},{1}] (color = {2})\r\n",
                     e.RowIndex, e.ColumnIndex, e.CellStyle.BackColor.Name);

                this.changedBackColors.Remove(e.CellStyle.BackColor);

                // TODO: change excel file
                // ...
            }
        }
    }
}

日志:

  • 更改单元格[0,0](颜色=蓝色)
  • Cell [?,?](color = Blue)
  • 发生CellStyleContentChanged
  • 更改单元格[0,1](颜色=红色)
  • Cell [?,?](color = Red)
  • 发生CellStyleContentChanged
  • Cell [0,0](color = Blue)
  • 发生CellFormatting
  • Cell [0,1](颜色=红色)
  • 发生CellFormatting