我正在研究一个类,我们称之为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文件。
为实现这一目标,我(未成功)尝试使用多种方法:
CellStyleContentChanged事件(问题:无法从事件处理程序获取Cell本身)。
CellFormatting事件(问题:事件上升了很多次,我无法理解其发生的原因)。
CellStyleChanged事件(问题:仅在Style属性更改时发生事件,但不会发生Style.BackColor事件。)
覆盖DataGridViewCellStyle类(问题:我不知道如何正确覆盖此类以及是否可以完成此类。)
有助于重现我的尝试的代码段:
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
// ...
}
}
}
}
}
}
}
}
}
我会很高兴得到任何建议和答案!
答案 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
// ...
}
}
}
}
日志: