我对我的一个工作项目的要求有问题。我正在做的是将数据表绑定到DataGridView(DGV)的数据源。然后我遍历DataGridView并检查单元格的值是否为1 *或2 **,并使用工具提示和红色背景格式化这些单元格。如果我使用按钮事件触发这一切,一切都很好。但是,如果我希望在使用DataBindingComplete事件加载表单时自动执行此操作,则它无法正常工作。问题是DataBindingComplete多次触发。我读了this SO question,这给了我一些选择尝试,但没有一个工作。这是代码:
public partial class TestForm2 : Form
{
private DataTable dt;
private int methodCalls = 0;
private bool isFormatted = false;
public TestForm2()
{
InitializeComponent();
buildDataTable();
dataGridView1.DataBindingComplete += dataGridView1_DataBindingComplete;
}
private void TestForm2_Load(object sender, EventArgs e)
{
bindData();
}
private void button1_Click(object sender, EventArgs e)
{
formatDataGridView();
}
private void bindData()
{
dataGridView1.DataSource = dt;
}
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
//If this code is commented out the program will work just fine
//by just clicking the button
//This was added to prevent formatDataGridView from executing more
//than once. Even though I unreg and rereg the event handler, the
//method was still being called 3 - 4 times. This successfully
//prevented that but only the *'s were removed and no red back color
//added to the cells.
if(!isFormatted)
{
formatDataGridView();
}
}
private void buildDataTable()
{
dt = new DataTable();
dt.Columns.Add("col1");
dt.Columns.Add("col2");
dt.Columns.Add("col3");
dt.Columns.Add("col4");
Random randNum = new Random();
for(int i = 0; i < 10; i++)
{
DataRow dr;
object[] rowItems = new object[dt.Columns.Count];
for(int j = 0; j < dt.Columns.Count; j++)
{
int number = randNum.Next(1, 20);
if(number % 7 == 0)
{
rowItems[j] = number + "*";
}
else if(number % 5 == 0)
{
rowItems[j] = number + "**";
}
else
{
rowItems[j] = number;
}
}
dr = dt.NewRow();
dr.ItemArray = rowItems;
dt.Rows.Add(dr);
}
}
private void formatDataGridView()
{
// I noticed that I needed to unregister the event handler to
// prevent DataBindingComplete from firing during the format
dataGridView1.DataBindingComplete -= dataGridView1_DataBindingComplete;
foreach(DataGridViewRow row in dataGridView1.Rows)
{
string originalCell;
string reformattedCell;
if(row.Cells["col1"].Value != null)
{
originalCell = row.Cells["col1"].Value.ToString();
if (originalCell.Count(c => c == '*') == 2)
{
reformattedCell = originalCell.Replace("**", "");
row.Cells["col1"].Value = reformattedCell;
row.Cells["col1"].Style.BackColor = Color.Red;
row.Cells["col1"].ToolTipText = "Divisible by 5";
}
else if (originalCell.Count(c => c == '*') == 1)
{
reformattedCell = originalCell.Replace("*", "");
row.Cells["col1"].Value = reformattedCell;
row.Cells["col1"].Style.BackColor = Color.Red;
row.Cells["col1"].ToolTipText = "Divisible by 7";
}
else
{
//do nothing
}
}
if (row.Cells["col2"].Value != null)
{
originalCell = row.Cells["col2"].Value.ToString();
if (originalCell.Count(c => c == '*') == 2)
{
reformattedCell = originalCell.Replace("**", "");
row.Cells["col2"].Value = reformattedCell;
row.Cells["col2"].Style.BackColor = Color.Red;
row.Cells["col2"].ToolTipText = "Divisible by 5";
}
if (originalCell.Count(c => c == '*') == 1)
{
reformattedCell = originalCell.Replace("*", "");
row.Cells["col2"].Value = reformattedCell;
row.Cells["col2"].Style.BackColor = Color.Red;
row.Cells["col2"].ToolTipText = "Divisible by 7";
}
else
{
//do nothing
}
}
if (row.Cells["col3"].Value != null)
{
originalCell = row.Cells["col3"].Value.ToString();
if (originalCell.Count(c => c == '*') == 2)
{
reformattedCell = originalCell.Replace("**", "");
row.Cells["col3"].Value = reformattedCell;
row.Cells["col3"].Style.BackColor = Color.Red;
row.Cells["col3"].ToolTipText = "Divisible by 5";
}
else if (originalCell.Count(c => c == '*') == 1)
{
reformattedCell = originalCell.Replace("*", "");
row.Cells["col3"].Value = reformattedCell;
row.Cells["col3"].Style.BackColor = Color.Red;
row.Cells["col3"].ToolTipText = "Divisible by 7";
}
else
{
//do nothing
}
}
if (row.Cells["col4"].Value != null)
{
originalCell = row.Cells["col4"].Value.ToString();
if (originalCell.Count(c => c == '*') == 2)
{
reformattedCell = originalCell.Replace("**", "");
row.Cells["col4"].Value = reformattedCell;
row.Cells["col4"].Style.BackColor = Color.Red;
row.Cells["col4"].ToolTipText = "Divisible by 5";
}
else if (originalCell.Count(c => c == '*') == 1)
{
reformattedCell = originalCell.Replace("*", "");
row.Cells["col4"].Value = reformattedCell;
row.Cells["col4"].Style.BackColor = Color.Red;
row.Cells["col4"].ToolTipText = "Divisible by 7";
}
else
{
//do nothing
}
}
}
// Reregistering the event handler
dataGridView1.DataBindingComplete += dataGridView1_DataBindingComplete;
isFormatted = true;
methodCalls++;
MessageBox.Show("Method Calls: " + methodCalls);
}
}
我不知道如何解决这个问题,但必须有办法。直到最近我才对DataBindingComplete不熟悉所以我肯定会在这里学到一些东西。感谢大家的帮助,并帮助我学习新东西!
答案 0 :(得分:6)
CellFormatting事件处理程序是我最终解决问题的路径。
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
string originalCell;
string reformattedCell;
if (this.dataGridView1.Columns[e.ColumnIndex].Name == "col1")
{
if(e.Value != null)
{
DataGridViewCell cell =
this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
originalCell = e.Value.ToString();
if (originalCell.Count(c => c == '*') == 2)
{
reformattedCell = originalCell.Replace("**", "");
cell.Value = reformattedCell;
cell.Style.BackColor = Color.Red;
cell.ToolTipText = "Divisible by 5";
}
else if (originalCell.Count(c => c == '*') == 1)
{
reformattedCell = originalCell.Replace("*", "");
cell.Value = reformattedCell;
cell.Style.BackColor = Color.Red;
cell.ToolTipText = "Divisible by 7";
}
else
{
//do nothing
}
}
}
if (this.dataGridView1.Columns[e.ColumnIndex].Name == "col2")
{
if (e.Value != null)
{
DataGridViewCell cell =
this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
originalCell = e.Value.ToString();
if (originalCell.Count(c => c == '*') == 2)
{
reformattedCell = originalCell.Replace("**", "");
cell.Value = reformattedCell;
cell.Style.BackColor = Color.Red;
cell.ToolTipText = "Divisible by 5";
}
else if (originalCell.Count(c => c == '*') == 1)
{
reformattedCell = originalCell.Replace("*", "");
cell.Value = reformattedCell;
cell.Style.BackColor = Color.Red;
cell.ToolTipText = "Divisible by 7";
}
else
{
//do nothing
}
}
}
if (this.dataGridView1.Columns[e.ColumnIndex].Name == "col3")
{
if (e.Value != null)
{
DataGridViewCell cell =
this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
originalCell = e.Value.ToString();
if (originalCell.Count(c => c == '*') == 2)
{
reformattedCell = originalCell.Replace("**", "");
cell.Value = reformattedCell;
cell.Style.BackColor = Color.Red;
cell.ToolTipText = "Divisible by 5";
}
else if (originalCell.Count(c => c == '*') == 1)
{
reformattedCell = originalCell.Replace("*", "");
cell.Value = reformattedCell;
cell.Style.BackColor = Color.Red;
cell.ToolTipText = "Divisible by 7";
}
else
{
//do nothing
}
}
}
if (this.dataGridView1.Columns[e.ColumnIndex].Name == "col4")
{
if (e.Value != null)
{
DataGridViewCell cell =
this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
originalCell = e.Value.ToString();
if (originalCell.Count(c => c == '*') == 2)
{
reformattedCell = originalCell.Replace("**", "");
cell.Value = reformattedCell;
cell.Style.BackColor = Color.Red;
cell.ToolTipText = "Divisible by 5";
}
else if (originalCell.Count(c => c == '*') == 1)
{
reformattedCell = originalCell.Replace("*", "");
cell.Value = reformattedCell;
cell.Style.BackColor = Color.Red;
cell.ToolTipText = "Divisible by 7";
}
else
{
//do nothing
}
}
}
}
答案 1 :(得分:3)
您需要更改:
请记住,在浏览数据以设置格式时,为了提高效率,如果CellStyles的类型有限,例如Good Result,Bad Result(我的代码实际上有大约11种默认样式)首先创建样式。
然后在检查单元格值时分配它们,并找出要使用的样式。
唯一需要注意的是,如果你改变例如Column = 12,Row = 4 cellstyle会以某种方式影响所有单元格“共享”相同的默认DataGridViewCellstyle。
e.g
Font bFont = new Font("Calibri", defFontSize, FontStyle.Bold); // Bold font
Font iFont = new Font("Calibri", defFontSize, FontStyle.Italic); // Italic font
Font nFont = new Font("Calibri", defFontSize); // Normal font
DataGridViewCellStyle dgvcsOKRESULT = new DataGridViewCellStyle()
{
Font = nFont,
ForeColor = Color.White,
BackColor = Color.Green,
};
DataGridViewCellStyle dgvcsBADRESULT = new DataGridViewCellStyle()
{
Font = bFont,
ForeColor = Color.White,
BackColor = Color.Red,
};
答案 2 :(得分:1)
从bindData方法调用formatDataGridView并忘记DataBinding事件:
private void bindData()
{
dataGridView1.DataSource = dt;
formatDataGridView();
}
或者这是不可能的?