谁能解释一下为什么这个代码
dataGridView1.Rows[0].HeaderCell.Value = 10;
什么都没显示而这个
dataGridView1.Rows[0].HeaderCell.Value = 10.ToString();
工作正常吗?
gajydyqb1#
这看起来像是一个bug,实际上不是,但是当你设置属性并且在相似的条件下得到不同的结果时,感觉就像是bug。发生的情况:[DataGridView].Rows[N].HeaderCell的类型为DataGridViewRowHeaderCell。FormattedValue属性不直接属于此类,它派生自DataGridViewHeaderCell,而DataGridViewHeaderCell又派生自DataGridViewCell(泛型类)。DataGridViewHeaderCell将默认的FormattedValue和Value类型设置为:
[DataGridView].Rows[N].HeaderCell
FormattedValue
DataGridViewHeaderCell
Value
private static Type defaultFormattedValueType = typeof(System.String); private static Type defaultValueType = typeof(System.Object);
当我们设定:
[DataGridView].Rows[N].HeaderCell.Value = 10;
Value存储为Object,装箱为int。如果我们在设置Value后立即检查**HeaderCell*对象,我们可以看到FormattedValue和FormattedValueType属性分别设置为"10"和System.String。这是因为这些属性值是由DataGridViewCell类别呼叫其GetFormattedValue()方法来撷取。FormattedValueType属性预设为System.String。因此, 看起来 * 此FormattedValue将在呈现Header内容时使用。当Header需要渲染时,DataGridViewRowHeaderCell将其FormattedValue设置为原始值(一个int):FormattedValueType被忽略。原因在GetContentBounds()方法的注解中(以及其他多个地方)进行了解释:
int
HeaderCell
FormattedValueType
"10"
System.String
DataGridViewCell
DataGridViewRowHeaderCell
内容界限是根据需要计算的 * [...]出于同样的原因,Row Header单元格不会引发CellFormatting事件。呈现Row Header单元格的私有PaintPrivate()方法接收表示int的formattedValue,而不是字符串。然后使用:
CellFormatting
formattedValue
string formattedString = formattedValue as string;
将formattedValue * 转换为字符串。由于formattedValue不是字符串,因此 cast 返回null,因此不呈现任何内容。当然,同样的条件也适用于DataGridViewCellPaintingEventArgs:当引发**CellPainting事件时,e.FormattedValue**属性会传回10(int)。如果我们设置以下内容,则返回"10":
null
CellPainting
e.FormattedValue
10
[DataGridView].Rows[N].HeaderCell.Value = "10"; // Or 10.ToString()
在本例中,string formattedString = formattedValue as string;返回一个字符串,并呈现该内容。现在,我们可以更好地理解为什么不能使用RowHeader单元格值来显示这种类型单元格中的内容:内容边界没有被精确地 * 考虑 * 并且呈现是糟糕的。要使用Row Header对行进行编号,我们需要处理CellPainting事件。
1条答案
按热度按时间gajydyqb1#
这看起来像是一个bug,实际上不是,但是当你设置属性并且在相似的条件下得到不同的结果时,感觉就像是bug。
发生的情况:
[DataGridView].Rows[N].HeaderCell
的类型为DataGridViewRowHeaderCell。FormattedValue
属性不直接属于此类,它派生自DataGridViewHeaderCell,而DataGridViewHeaderCell又派生自DataGridViewCell(泛型类)。DataGridViewHeaderCell
将默认的FormattedValue
和Value
类型设置为:当我们设定:
Value存储为Object,装箱为
int
。如果我们在设置Value后立即检查**
HeaderCell
*对象,我们可以看到FormattedValue
和FormattedValueType
属性分别设置为"10"
和System.String
。这是因为这些属性值是由
DataGridViewCell
类别呼叫其GetFormattedValue()方法来撷取。FormattedValueType
属性预设为System.String
。因此, 看起来 * 此
FormattedValue
将在呈现Header内容时使用。当Header需要渲染时,
DataGridViewRowHeaderCell
将其FormattedValue
设置为原始值(一个int
):FormattedValueType
被忽略。原因在GetContentBounds()方法的注解中(以及其他多个地方)进行了解释:内容界限是根据需要计算的 * [...]
出于同样的原因,Row Header单元格不会引发
CellFormatting
事件。呈现Row Header单元格的私有PaintPrivate()方法接收表示
int
的formattedValue
,而不是字符串。然后使用:
将
formattedValue
* 转换为字符串。由于formattedValue
不是字符串,因此 cast 返回null
,因此不呈现任何内容。当然,同样的条件也适用于DataGridViewCellPaintingEventArgs:当引发**
CellPainting
事件时,e.FormattedValue
**属性会传回10
(int
)。如果我们设置以下内容,则返回
"10"
:在本例中,
string formattedString = formattedValue as string;
返回一个字符串,并呈现该内容。现在,我们可以更好地理解为什么不能使用RowHeader单元格值来显示这种类型单元格中的内容:内容边界没有被精确地 * 考虑 * 并且呈现是糟糕的。要使用Row Header对行进行编号,我们需要处理CellPainting事件。