Recently I've written a custom DataGridViewColumn to host a progress bar. The column class itself has a property that I'd like to propagate to all the cells of the column. I use this code to implement it:-
<DefaultValue(5I)> _
Public Property BlockWidth() As Integer
Get
Return _blockWidth
End Get
Set(ByVal value As Integer)
_blockWidth = value
Me.ColumnCells.ForEach(Sub(cell) cell.BlockWidth = value)
End Set
End Property
And this:-
Private ReadOnly Property ColumnCells As IEnumerable(Of DataGridViewProgressBarCell)
Get
If Me.DataGridView IsNot Nothing Then
Return Me.DataGridView.Rows.
Cast(Of DataGridViewRow).
Where(Function(r) TypeOf r.Cells.Item(Me.Index) Is DataGridViewProgressBarCell).
Select(Function(r) DirectCast(r.Cells.Item(Me.Index), DataGridViewProgressBarCell))
Else
Return New DataGridViewProgressBarCell() {}
End If
End Get
End Property
Now this works at runtime. If I change the BlockWidth property of a column at runtime, all the cells of the column will change to reflect the property change but I cannot seem to get this to work at design time. At design time the cell doesn't change, the property change persists but the cell doesn't change. I've tried all manner of trickery and it refuses to work. Please can anyone tell me what I'm doing wrong ?
Nevermind. I figured it out. I had to set the BlockWidth property on the cell template(through the CellTemplate property of the column class) object passed to the constructor of the column object. Also, I forgot to clone the BlockWidth property on the progress bar's cell class.
<DefaultValue(5I)> _
Public Property BlockWidth() As Integer
Get
Return _blockWidth
End Get
Set(ByVal value As Integer)
_blockWidth = value
'For changes to be reflected at runtime
Me.ColumnCells.ForEach(Sub(cell) cell.BlockWidth = value)
'For changes to be reflected at design time
Me.Template.BlockWidth = _blockWidth
If Me.DataGridView IsNot Nothing Then
Me.DataGridView.InvalidateColumn(Me.Index)
End If
End Set
End Property
Thanks you all for your comments and answers. :)