Datagridview not changing image in cell - vb.net

I am working with DataGridViewObject in my Windows form, using VB.NET. I have three columns that need to display icons. But, based on some info from row, that icons will be shown or not. My problem is that image won't change when I change its value. Basically, I define my columns like this:
Dim column1 As DataGridViewImageColumn = New DataGridViewImageColumn()
column1.Image = My.Resources.image1
column1.Width = 30
dw.Columns.Add(column1)
Dim column2 As DataGridViewImageColumn = New DataGridViewImageColumn()
column2.Image = My.Resources.image2
column2.Width = 30
dw.Columns.Add(column2)
Dim column3 As DataGridViewImageColumn = New DataGridViewImageColumn()
column3.Image = My.Resources.image3
column3.Width = 30
dw.Columns.Add(column3)
After the data is filled, I am looping through rows, and if I do not want to show the images in that row, I do:
Dim cell1 As DataGridViewImageCell = row.Cells(9)
Dim cell2 As DataGridViewImageCell = row.Cells(10)
Dim cell3 As DataGridViewImageCell = row.Cells(11)
cell1.Value = Nothing
cell2.Value = Nothing
cell3.Value = Nothing
But, my images stay. Anyone knows what am I missing?

You are using some unbound DataGridViewImageColumn and as mentioned in documents, The Image property specifies an image that is displayed in cells with no values when the column is not data-bound.
So by setting a cell value to null, you are forcing the cell to show the Image property.
To solve the problem:
For your columns set column.DefaultCellStyle.NullValue = Nothing
Don't set the Image property.
Each time you want to show the image, assign the image to Value property of cell.
You can set value of Cell manually in a loop or using CellFormatting event. For example:
Private Sub DataGridView1_CellFormatting(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) _
Handles DataGridView1.CellFormatting
If (e.RowIndex >= 0 AndAlso e.ColumnIndex = 2) Then
If (e.RowIndex Mod 2 = 0) Then 'Use any criteria which you need, it's a test
e.Value = My.Resources.Image1
Else
e.Value = DBNull.Value
e.CellStyle.NullValue = Nothing
End If
End If
' Do the same for other image columns.
End Sub

Related

How to set DataGridView Rows FontStyle with condition at loading time?

How to change the Font Style of all Rows of a DataGridView based on a conditions?
My condition is if Cell Value Equal 0 then FontStyle = Strikeout otherwise Regular
Private Function DetailGridViewSetStyle()
Dim dgv As DataGridView = DetailDataGridView
Dim dgvInd As Integer = dgv.CurrentRow.Index
For cc As Integer = 0 To dgv.ColumnCount - 1
If dgv.Item(4, dgvInd).Value = 0 Then
dgv.DefaultCellStyle.Font = New Font("ARIAL", 8, FontStyle.Strikeout)
ElseIf dgv.Item(4, dgvInd).Value = 1 Then
dgv.DefaultCellStyle.Font = New Font("ARIAL", 8, FontStyle.Regular)
End If
Next
End Function
Only use "Function" if you need to return something, that's not your case, use Sub instead.
dgv.DefaultCellStyle.Font will set font style for all your datagrid, you need to set font style from a specify row, then use row.DefaultCellStyle.Font
If I understood your question, here's the code that you need:
Private Sub DetailGridViewSetStyle()
Dim dgv As DataGridView = DetailDataGridView
For Each row As DataGridViewRow In dgv.Rows
Dim Value As Boolean = CBool(row.Cells(4).Value)
If Value = False Then
row.DefaultCellStyle.Font = New Font("ARIAL", 8, FontStyle.Strikeout)
Else
row.DefaultCellStyle.Font = New Font("ARIAL", 8, FontStyle.Regular)
End If
Next
End Sub
If your DataGridView is bound to a data source, you may want to format the grid's Rows when the DataBinding is complete.
Subscribe to the DataBindingComplete event.
After that, you need to handle Cell value changes, to format the Row based on the value of a Column in the current Row.
Subscribe to the CellValueChanged event.
I'm using a helper method to determine what is the current what is the value of the Cell that determines the Font Style change, what is the current Font of its OwningRow, then change the Font Style to the Style specified if all criteria are met, otherwise, revert to default Font Style.
Note: the DataGridViewRow.DefaultCellStyle may be null, since the Row may inherit the Font from the DataGridView.DefaultCellStyle, so we need to check the DataGridViewRow.InheritedStyle value.
There's an assignment that uses a coalesce expression in the helper method:
Dim rowFont = If(row.DefaultCellStyle.Font, row.InheritedStyle.Font)
If this syntax is not available in your VB.Net version, use an extended form as:
Dim rowFont = If(row.DefaultCellStyle.Font Is Nothing, row.InheritedStyle.Font, row.DefaultCellStyle.Font)
Or do nothing if the current Cell value is null (Nothing) or is DbNull.Value: it can be if the DataGridView.DataSource is set to a DataTable, for example.
If you want to interpret null Cell values as 0, change the code accordingly.
Private Sub DetailDataGridView_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DetailDataGridView.CellValueChanged
If e.ColumnIndex = 4 Then
ToggleRowFontStyle(Of Integer)(DetailDataGridView(4, e.RowIndex), 0, FontStyle.Strikeout)
End If
End Sub
Private Sub DetailDataGridView_DataBindingComplete(sender As Object, e As DataGridViewBindingCompleteEventArgs) Handles DetailDataGridView.DataBindingComplete
For Each row As DataGridViewRow In DetailDataGridView.Rows
ToggleRowFontStyle(Of Integer)(DetailDataGridView(4, row.Index), 0, FontStyle.Strikeout)
Next
End Sub
Helper method:
Private Sub ToggleRowFontStyle(Of T)(cell As DataGridViewCell, toggleValue As T, toggleFontStyle As FontStyle)
If cell.Value Is Nothing OrElse cell.Value Is DBNull.Value Then Return
Dim row As DataGridViewRow = cell.OwningRow
Dim cellValue As T = CType(Convert.ChangeType(cell.Value, GetType(T)), T)
Dim rowFont = If(row.DefaultCellStyle.Font, row.InheritedStyle.Font)
If cellValue.Equals(toggleValue) Then
If rowFont.Style <> toggleFontStyle Then
rowFont = New Font(rowFont, toggleFontStyle)
End If
Else
If rowFont.Style = toggleFontStyle Then
rowFont = New Font(rowFont, FontStyle.Regular)
End If
End If
row.DefaultCellStyle.Font = rowFont
End Sub

DataGridViewImageColumn doesn't change value

I'm trying to change the image of a cell inside DataGridViewImageColumn when the value of another cell is OK or NO.
I've created the column with this code
Dim NewImageProd As New DataGridViewImageColumn
NewImageProd.Image = My.Resources.Smile1
NewImageProd.Name = "IMAGE"
NewImageProd.ImageLayout = DataGridViewImageCellLayout.Zoom
NewImageProd.DisplayIndex = 0
NewImageProd.Width = 70
DGDati.Columns.Add(NewImageProd)
Later I've done the check with this code
For Idx = 0 To DGDati.RowCount - 1
Select Case DGDati("OTHERVALUE", Idx).Value.ToString
Case "OK"
DGDati.Rows(Idx).Cells("IMAGE").Value = My.Resources.Smile2
Case "NO"
DGDati.Rows(Idx).Cells("IMAGE").Value = My.Resources.Smile3
End Select
Next
Call DGDati.RefreshEdit()
But nothing happen.
What am I doing wrong?
Use DataGridView.CellFormatting event that occurs when the contents of a cell need to be formatted for display. Using this event you don't need to refresh DataGridView or data.
Private Sub DGDati_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles DGDati.CellFormatting
If e.ColumnIndex = -1 Or e.RowIndex = -1 Then Exit Sub
With Me.DGDati
If .Columns(e.ColumnIndex).Name = "IMAGE" Then
If .Rows(e.RowIndex).Cells("OTHER_VALUE").Value = "OK" Then
e.Value = My.Resources.Smile2
ElseIf .Rows(e.RowIndex).Cells("OTHER_VALUE").Value = "NO"
e.Value = My.Resources.Smile3
Else
e.Value = My.Resources.Smile1
End If
End If
End With
End Sub
Also follow advice in the comments to never reuse images from Resources like that.

Change value of row to image based on cell value

Hi everyone i am doing a windows form which is created in visual studio 2005, wherein it displays data in datagridview. I have a column "colImg" that will display 1 and 0. But i need to display a red image when the value of cell of colImg is 0 and green image when the value is 1. I have a code but the problem is it only displays image which is green but i have a values which is 0. Is there any problem on my code?
Private Sub grdView_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles grdView.CellFormatting
If grdView.Columns(e.ColumnIndex).Name.Equals("colImg") Then
Dim value As Integer
If TypeOf e.Value Is Integer Then
value = DirectCast(e.Value, Integer)
e.Value = My.Resources.Resources.NotYet
Else
For i As Integer = 0 To grdView.RowCount
If value = 0 Then
e.Value = My.Resources.Resources.Red
Else
e.Value = My.Resources.Resources.Green
End If
Next
End If
End If
There are several solutions for your question, I will provide one of them.
You need two columns in your DataGrid.
One is to hold the raw data (0 or 1); in my example I called it colValue.
The other is to hold only the image (red or green); named colImg.
colValue is not shown in the grid :
'Set colValue invisible which is first column in my example
DataGridView1.Columns(0).Visible = False
Use the CellValueChanged event to set the image of the colImg cell:
If e.ColumnIndex = 0 AndAlso Not isInit Then 'Value column has changed and we are not in Form Initializing
Dim valueCell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex)
Dim imgCell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex + 1) 'Whatever index your colImg is
If Integer.Parse(valueCell.Value.ToString()) = 1 Then
imgCell.Value = My.Resources.Green
Else
imgCell.Value = My.Resources.Red
End If
End If
To avoid that the event code breaks when the Form and thus the DataGridView is being initilized I created a local variable isInit and set it before and after the initialization:
Public Class Form1
Private isInit As Boolean
Public Sub New()
isInit = True
InitializeComponent()
isInit = False
...
End Sub
...
End Class
Sample Data:
DataGridView1.Rows(0).Cells(0).Value = 1
DataGridView1.Rows(1).Cells(0).Value = 0
DataGridView1.Rows(2).Cells(0).Value = 0
DataGridView1.Rows(3).Cells(0).Value = 1
Outcome:

datagrid view combobox item selection vb.net

I have a datagridview which I have furnished using the following code...
The trouble I have though is with the combobox column.
First off how can I have a preset value already selected in the combobox.
Secondly When I run my code I have to click the combobox's twice how can I change this to only having to click them once?
'CREATE DATAGRIVIEW 1 COLUMN LAYOUT...S
DataGridView1.ColumnCount = 8
DataGridView1.Columns(0).Name = "QTY"
DataGridView1.Columns(1).Name = "H"
DataGridView1.Columns(2).Name = "L"
DataGridView1.Columns(3).Name = "W"
DataGridView1.Columns(4).Name = "ANG 1"
DataGridView1.Columns(5).Name = "ANG 2"
DataGridView1.Columns(6).Name = "MAT"
DataGridView1.Columns(7).Name = "THK"
Dim ComboBoxColumn As New DataGridViewComboBoxColumn()
ComboBoxColumn.HeaderText = "TYPE"
ComboBoxColumn.Name = "ComboBoxColumn"
ComboBoxColumn.MaxDropDownItems = 5
ComboBoxColumn.Items.Add("NON")
ComboBoxColumn.Items.Add("SNG")
ComboBoxColumn.Items.Add("PER")
ComboBoxColumn.Items.Add("PAR")
ComboBoxColumn.Items.Add("AXS")
DataGridView1.Columns.Insert(8, ComboBoxColumn)
Dim checkBoxColumn As New DataGridViewCheckBoxColumn()
checkBoxColumn.HeaderText = "IDW"
checkBoxColumn.Name = "checkBoxColumn"
DataGridView1.Columns.Insert(9, checkBoxColumn)
'CREATE DATAGRIVIEW 1 COLUMN LAYOUT...E
If you mean a defaultvalue for the combobox:
Private Sub DataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
If (e.ColumnIndex = 8) Then ' your combo column index
e.Value = "PER"
End If
End Sub
The selection in the combo box reflects the Value of the cell. If you want something to be selected then you have to set the Value of the cell accordingly.
Your second issue, which is unrelated and should therefore have been asked in an unrelated post, is as a result of the EditMode of the grid. Change that to the appropriate value for the behaviour you want.

Changing double clicking activation on Combo box cell to single click?

I have a setup in my code where there is a datagridview. For each row I have a combo box cell that I have a separate combo box cell since I want a different selection of items for each cell.
Problem : The cell only drops down when the arrow is double clicked. How can I change the cell formatting, or possibly a cell click event, so that the cell response to just one click?
Here's my cell creation code. Frankly, I didn't start any other code since I didn't know what event to touch or call. Is there a property I can edit?
Code:
'add items to combobox list
Dim comboCell As New DataGridViewComboBoxCell
comboCell.FlatStyle = FlatStyle.Flat
Dim resolutionList As New List(Of cmbStruct)
Dim currentResIndex As Integer = 0
'create list of resolutions
For j As Integer = 0 To resolutions.Length - 1
Dim resClass As New cmbStruct
resClass.Name = resolutions(j)
resClass.ID = resolutions(j)
resolutionList.Add(resClass)
comboCell.Items.Add(resolutions(j))
Next
'set combocell values
comboCell.DisplayMember = "Name"
comboCell.ValueMember = "ID"
'set the default value to the current resolution index
Try
comboCell.Value = resolutions(currentResIndex)
Catch ex As Exception
End Try
comboCell.ValueType = GetType(cmbStruct)
comboCell.DataSource = resolutionList
editCameraTable("Resolution", i) = comboCell
Next
Change the EditMode property:
DataGridView1.EditMode = DataGridViewEditMode.EditOnEnter
There seems to be a nearly identical question and a very good answer. It involves using the click_event. Here is the link:
How to manually drop down a DataGridViewComboBoxColumn?
In the link:
Private Sub cell_Click(ByVal sender As System.Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
DataGridView1.BeginEdit(True)
If DataGridView1.Rows(e.RowIndex).Cells(ddl.Name).Selected = True Then
DirectCast(DataGridView1.EditingControl, DataGridViewComboBoxEditingControl).DroppedDown = True
End If
End Sub