1

How to remove null image in datagridview column image in vb.net?

Is there a way to remove null image in datagridview column image?

Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress

    If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Enter) Then
        item.Add(New item With {
            .CodeProduct = TextBox1.Text
        })
        Grid.Bind(item)
        TextBox1.Clear()
    End If
End Sub

Public Class item
    Public Property No() As Integer
    Public Property CodeProduct() As String
    Public Function GetAvatar() As DataGridViewAvatar
        Return New DataGridViewAvatar() With {
            .Value = CType(Me.CodeProduct, String),
            .Icon = Image.FromFile("money.png")
        }
    End Function

remove null image in datagridview column image

Before use CustomImageCell

Before use CustomImageCell

after use CustomImageCell

after use CustomImageCell

Jimi
  • 29,621
  • 8
  • 43
  • 61
roy
  • 693
  • 2
  • 11
  • 1
    Does this answer your question? [Changing Appearance of Null / Empty Image on DataGridView](https://stackoverflow.com/questions/13744502/changing-appearance-of-null-empty-image-on-datagridview) – TnTinMn Jun 20 '23 at 15:30
  • @TnTinMn That doesn't work for the NewRow Value. You need a custom Cell that overrides `DefaultNewRowValue` (which is usually read-only). Also, IIRC, the `Image` property should be set to an empty Bitmap – Jimi Jun 20 '23 at 16:17
  • @Jimi, there no need for a custom cell to override default values for a new row. That is what the [DataGridView.DefaultValuesNeeded event](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridview.defaultvaluesneeded) is for. If the OP is only interested in the NewRow, then setting image cell value to Nothing in that event in addition to configuring the imageColumn.DefaultCellStyle.NullValue should work. – TnTinMn Jun 20 '23 at 20:49
  • @TnTinMn That event is raised when you actually focus (enter) the NewRow object in the UI. Setting the Column's DefaultCellStyle is related to the default values of data, so the grid presentation of the Image in the NewRow doesn't change. Or, it just changes when you actually have focus on the NewRow (because it's then a DataRow), but switches back to the default ErrorImage when the focus goes away -- You would also need to determine, each time, which Column is a DataGridViewImageColumn and do something. Replacing a Cell template with a custom one is simple and *definitive* – Jimi Jun 20 '23 at 21:46
  • @TnTinMn , Thanks for your response, I tried with this `Does this answer your question? Changing Appearance of Null / Empty Image on DataGridView ` still does not eliminate Null/Empty Image – roy Jun 21 '23 at 01:37
  • @TnTinMn , `That is what the DataGridView.DefaultValuesNeeded event is for.` still does not eliminate Null/Empty Image – roy Jun 21 '23 at 01:38
  • @Jimi , Thanks for your response. `Replacing a Cell template with a custom one is simple and definitive` How can I do this please guide from you – roy Jun 21 '23 at 01:40

2 Answers2

1

To replace the default ImageInError object (Icon or Bitmap, depending on the .NET version) that is presented when a DatGridViewImageCell has no value or as the placeholder in the New Row object, you can use a custom DatGridViewImageCell that sets the DefaultNewRowValue and Style.NullValue properties in its Constructor.

Then replace the CellTemplate of a DataGridViewImageColumn with this one.
Done like this, you set the value just once and it's used everywhere. No need to handle events and, possibly, leak graphic resources in the meanwhile.

Sample class:

Friend Class CustomImageCell
    Inherits DataGridViewImageCell
    Public Sub New()
        Me.New(Nothing)
    End Sub
    Public Sub New(ByVal defaultImage As Object)
        MyBase.New(False)
        DefaultNewRowValue = defaultImage
        Style.NullValue = defaultImage
    End Sub

    ' Handle as needed, if necessary
    Public Overrides ReadOnly Property DefaultNewRowValue As Object
End Class

To replace the default Cell with this one and set a null value (default), for example:

For Each col In [Some DataGridView].Columns.OfType(Of DataGridViewImageColumn)()
    col.CellTemplate = New CustomImageCell()
Next

Or specify a different object in the Constructor You could also build a custom DataGridViewImageColumn that uses this Cell as CellTemplate. It would also appear in the Designer of the DataGridView when new Columns are added to the grid using the standard tool

Jimi
  • 29,621
  • 8
  • 43
  • 61
  • Does your code change the size of the image or icon other than the null image? I attach it in the post – roy Jun 21 '23 at 04:55
  • No. But you can change this behavior modifying the `ImageLayout` property in either the custom Cell or the Column to, e.g., `DataGridViewImageCellLayout.Zoom` or `.Stretch` – Jimi Jun 21 '23 at 04:59
  • `ImageLayout = System.Windows.Forms.DataGridViewImageCellLayout.Zoom` Actually, I've done it as you said. But this changes the size after use of your code is there anything that needs to be added in your code – roy Jun 21 '23 at 05:11
  • You probably have done that before replacing the Cell Template, so the setting is reset -- As mentioned, you can change the default behavior of the Cell, setting the `ImageLayout` Property (you can add it right after `Style.NullValue = defaultImage`), or after you have replaced the Cell of the Image Column (applies to either the Cell or the Column; - you could do that also in the loop shown here) – Jimi Jun 21 '23 at 05:18
  • `Style.NullValue = defaultImage ImageLayout = System.Windows.Forms.DataGridViewImageCellLayout.Zoom` Thank you I use it like this so the size of the image or icon becomes appropriate . `InitializeComponent() For Each col In grid.Columns.OfType(Of DataGridViewImageColumn)() col.CellTemplate = New CustomImageCell() Next` or `grid.Bind(itemtransfer) For Each col In grid.Columns.OfType(Of DataGridViewImageColumn)() col.CellTemplate = New CustomImageCell() Next` one more better I use loop code from you after InitializeComponent/form load or after binding to datagridview please guide – roy Jun 21 '23 at 06:11
  • After you bind the DGV, if you need to auto-generate the Columns. In either the Form Constructor or Form.Load, it's the same thing (in relation to this specific requirement). Just remember that when you replace the Image Cell, any setting that you may have changed before (in relation to the Image Column) are reset. To set defaults, you could use the `CustomImageCell` class directly (as you're doing now with the `ImageLayout` property) – Jimi Jun 21 '23 at 06:19
0

this solution DataGridViewImageCell.DefaultNewRowValue so that the new row image does not appear 'null image' (box with an 'x')

  Private Sub grid_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles grid.CellFormatting
            If (e.ColumnIndex = 0) Then
                Dim grdCell As DataGridViewImageCell = CType(grid(e.ColumnIndex, e.RowIndex), DataGridViewImageCell)
                If grdCell.Value Is grdCell.DefaultNewRowValue Then
                    e.Value = New Bitmap(1, 1)
                End If
            End If
        End Sub
roy
  • 693
  • 2
  • 11
  • You're leaking one Bitmap per `CellFormatting` event call (possibly, thousands; actually, undetermined). If you want to do it this ways (but see the notes I've written), create a Bitmap beforehand and use just that single object – Jimi Jun 21 '23 at 03:59
  • @Jimi , I agree with your answer – roy Jun 21 '23 at 04:38