提问人:user2970749 提问时间:1/20/2021 更新时间:1/22/2021 访问量:39
如何避免 datagridrow 突出显示函数在 Null 上轰炸?
How do I avoid datagridrow highlight function bombing out on Null?
问:
我有一个函数,旨在突出显示某些单元格彼此不匹配的行。这一直有效,直到它命中一个不包含任何内容的单元格,然后它作为 nullrefexception 轰炸出来。我知道我在这里错过了一些简单的东西,但我正在用头撞墙试图弄清楚! 提前致谢。
private void highlightrow()
{
int rowcnt = 0;
dataGridView1.ClearSelection();
int deviceNameColIndex = dataGridView1.Columns["cDeviceName"].Index;
int deviceNameColIndex2 = dataGridView1.Columns["cDeviceName2"].Index;
int driverVerColIndex = dataGridView1.Columns["cDriverVersion"].Index;
int driverVerColIndex2 = dataGridView1.Columns["cDriverVersion2"].Index;
int driverProviderName = dataGridView1.Columns["cdriverProviderName"].Index;
int driverProviderName2 = dataGridView1.Columns["cdriverProviderName2"].Index;
try
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
rowcnt++;
if (row.Cells[driverVerColIndex].Value.ToString() != row.Cells[driverVerColIndex2].Value.ToString() ||
row.Cells[driverProviderName].Value.ToString() != row.Cells[driverProviderName2].Value.ToString() ||
row.Cells[deviceNameColIndex].Value.ToString() != row.Cells[deviceNameColIndex2].Value.ToString()
)
{
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.YellowGreen;
row.Selected = true;
}
}
}
catch (NullReferenceException) { }
}
How do I skip null cells?
答:
谢谢你的想法。我以前尝试过检查空值,但仍然遇到问题,所以正在寻找一些实际的例子。碰巧的是,我已经设法对其进行了排序,尽管仍然觉得可以做得更好:
private void highlightrow()
{
int rowcnt = 0;
dataGridView1.ClearSelection();
int deviceNameColIndex = dataGridView1.Columns["cDeviceName"].Index;
int deviceNameColIndex2 = dataGridView1.Columns["cDeviceName2"].Index;
int driverVerColIndex = dataGridView1.Columns["cDriverVersion"].Index;
int driverVerColIndex2 = dataGridView1.Columns["cDriverVersion2"].Index;
int driverProviderName = dataGridView1.Columns["cdriverProviderName"].Index;
int driverProviderName2 = dataGridView1.Columns["cdriverProviderName2"].Index;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
rowcnt++;
foreach (DataGridViewCell cell in row.Cells)
{
string val = cell.Value as string;
if (String.IsNullOrEmpty(val))
{ }
else
{
try
{
if (
row.Cells[driverVerColIndex].Value.ToString() != row.Cells[driverVerColIndex2].Value.ToString() ||
row.Cells[driverProviderName].Value.ToString() != row.Cells[driverProviderName2].Value.ToString() ||
row.Cells[deviceNameColIndex].Value.ToString() != row.Cells[deviceNameColIndex2].Value.ToString()
)
{
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.YellowGreen;
row.Selected = true;
}
}
catch { }
}
}
}
}
评论
null
null
if
null
null.
null
null.
我的评论没有冒犯的意思。我只是想推动你找到一个更好的解决方案。你是否选择尝试寻找更好的解决方案取决于你。为了捍卫我的评论,特别是关于通过列的循环正在产生的不良副作用......我只是想指出“为什么”这种方法会产生一些不希望/意想不到的结果。如果它不是有用的评论,请原谅我。foreach
使用当前发布的示例,下面是一种可能的“更好”方法,当尝试避免 null 引用异常时,特别是在循环遍历DataGridView.
对于初学者来说,当遍历网格中的行并检查单元格值时,单元格值“总是”有可能在某些情况下,您“可能”假设单元格值不是,但是,即使在极少数情况下,作为编码员,如果单元格“以某种方式”并且代码没有检查这一点......然后代码崩溃。后果太严重,不能忽视此检查。null.
null,
null
因此,当循环遍历网格的单元格时......在我们尝试调用其方法之前检查这些值是明智的。null
ToString
检查值的一个地方是该行是否为网格“新”行。如果 grid 的属性设置为 AND 且 grids 数据源允许新行,则可以保证该行中的单元格为 null。因此,在遍历行时,检查此新行将消除检查单元格的需要。我们知道它们都是这样,所以我们可以“跳过”那一行。null
AllowUsersToAddRows
true
null
您可以考虑简单地将 grids 属性更改为并跳过此检查,但是,如果以后该属性更改为 ?如果我们“总是”检查这个“新”行,无论它是否存在,都将允许代码工作,而不管属性是什么。AllowUserToAddRows
false
true
AllowUserToAddRows
因此,在循环中通过行的第一次检查将是对新行的检查......foreach
foreach (DataGridViewRow row in dataGridView1.Rows) {
if (!row.IsNewRow) { … //this row it NOT the new row … }
这将消除“新”行;但是,我们仍然需要检查每个单元格。在这种情况下,代码必须检查六 (6) 个值,然后代码需要一次比较六个 (6) 个值两个。使用一堆语句可能会变得混乱。Cell.Value
null
if
因此,如果我们创建一个方法来检查两个单元格值并返回单元格值是否相等以及是否不相等,它可能会有所帮助。这应该会减少我们需要的语句数量。这种方法可能看起来像......true
false
if
private bool CellsAreEqual(DataGridViewCell cell1, DataGridViewCell cell2) {
if (cell1.Value == null && cell2.Value == null) {
return false;
}
if (cell1.Value != null && cell2.Value != null) {
return cell1.Value.ToString().Equals(cell2.Value.ToString());
}
else {
// one cell is null the other cell is not null
return false;
}
代码逻辑假定,如果一个或两个单元格是 ,则单元格不相等。首先检查两个单元格是否都是,如果是,则返回 如果一个单元格是而另一个单元格不是,则返回 ,否则我们可以安全地调用每个方法。null
null
false.
null
null
false
Cell.Value.ToString
最后,使用上述方法和新的行信息,我们可以将方法更改为类似...highlightrow
private void highlightrow() {
dataGridView1.ClearSelection();
foreach (DataGridViewRow row in dataGridView1.Rows) {
if (!row.IsNewRow) {
if (!CellsAreEqual(row.Cells["cDriverVersion"], row.Cells["cDriverVersion2"]) ||
!CellsAreEqual(row.Cells["cdriverProviderName"], row.Cells["cdriverProviderName2"]) ||
!CellsAreEqual(row.Cells["cDeviceName"], row.Cells["cDeviceName2"])) {
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.YellowGreen;
row.Selected = true;
}
}
else {
// ignore new row
}
}
}
我希望这是有道理的。
评论
Value
null
ToString
row.Cells[xxx].Value.ToString()
Value
null
null
Value
null
if (row.Cells[driverVerColIndex].Value != null) {…}
ToString
AllowUsersToAddRows
true
null.