DataGridViewImageColumn doesn't change value - vb.net

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.

Related

Split string into Sub String

I Am Using Vb.net. My idea is when I paste (ctrl+v) for example this character :
AHAKAPATARAE
I Have 6 textboxes.
it would automatically paste them in textboxes one by one in order!
so
txtBox1 will contain : AH
txtBox2 : AK
txtBox3 : AP
txtBox4 : AT
texbox5 : AR
texbox6 : AE
The automation of inserting Licence Keys will ease so much
so that user will not work so hard to cut & paste each two digits!
so any suggestion of doing auto-fill inside textboxes..?
Thanks.
This will allow the paste into the first textbox, as well as move forward correctly if the user types the whole thing manually starting in the first box:
Private Sub txtBox1_TextChanged(sender As Object, e As EventArgs) Handles txtBox6.TextChanged, txtBox5.TextChanged, txtBox4.TextChanged, txtBox3.TextChanged, txtBox2.TextChanged, txtBox1.TextChanged
Dim TB As TextBox = DirectCast(sender, TextBox)
Dim value As String = TB.Text
If value.Length > 2 Then
TB.Text = value.Substring(0, 2)
Dim TBs() As TextBox = {txtBox1, txtBox2, txtBox3, txtBox4, txtBox5, txtBox6}
Dim index As Integer = Array.IndexOf(TBs, TB)
If index > -1 AndAlso index < (TBs.Length - 1) Then
index = index + 1
TBs(index).Text = value.Substring(2)
TBs(index).Focus()
TBs(index).SelectionStart = TBs(index).TextLength
End If
End If
End Sub
There are definitely many more ways this could be accomplished...
Handle the key down event on textbox 1
Private Sub txtBox1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles txtBox1.KeyDown
If e.Modifiers = Keys.Control AndAlso e.KeyCode = Keys.V Then
' Get Clipboard Text
Dim cpText as String = My.Computer.Clipboard.GetText()
' Assign
txtBox1.Text = cpText.Substring(0, 2)
txtBox2.Text = cpText.Substring(2, 2)
txtBox3.Text = cpText.Substring(4, 2)
txtBox4.Text = cpText.Substring(6, 2)
txtBox5.Text = cpText.Substring(8, 2)
txtBox6.Text = cpText.Substring(10, 2)
'the event has been handled manually
e.Handled = True
End If
End Sub
Another option is to have one masked textbox event. Might be easier

Datagridview not changing image in cell

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

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:

Formatting rows in a datagridview

I have a few datagridview's, listing different bits and bobs from a mysql database.
One of them has a column called 'outcome'.
This can be either 'Yes', 'Pending' or 'No'.
I need to format this list based on that value.
I'm using the following at the moment...
Private Sub nb_myleads_dgv_CellFormattin(ByVal sender As Object, ByVal e As DataGridViewCellFormattingEventArgs) Handles nb_myleads_dgv.CellFormatting
If e.ColumnIndex = nb_myleads_dgv.Columns("outcome").Index Then
If e.Value.ToString = "Yes" Then
nb_myleads_dgv.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.DarkGreen
ElseIf e.Value.ToString = "Pending" Then
nb_myleads_dgv.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.DarkOrange
ElseIf e.Value.ToString = "No" Then
nb_myleads_dgv.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.DarkRed
End If
End sub
End If
It seem that I have to have my column 'outcome' visible in the DGV for this to work.
I have gotten around this by setting this column width to 3 pixels, but that seems a little dirty. Is it not possible to format cells in a datagridview based on the value of a hidden column?
Thanks in advance
Why not just loop through the rows with a for each and colorize based on the cell value. It won't matter if it's visible or not.
For Each row As DataGridViewRow In DataGridView1.Rows
If Not row.IsNewRow Then
Select Case row.Cells(2).Value.ToString
Case "Yes"
row.DefaultCellStyle.BackColor = Color.DarkGreen
Case "Pending"
row.DefaultCellStyle.BackColor = Color.DarkOrange
Case "No"
row.DefaultCellStyle.BackColor = Color.DarkRed
End Select
End If
Next
Where in this case, column 3 (cells(2) is hidden. You would do this after populating the grid instead of in the cellformatting
I believe your problem is that cell has to be visible, otherwise it will never pass if statement.
The CellFormatting event occurs every time each cell is painted, so
you should avoid lengthy processing when handling this event. This
event also occurs when the cell FormattedValue is retrieved or its
GetFormattedValue method is called.
Link
I would get rid off this if statement and do something like this:
Dim str as string = dataGridView1.Rows[e.RowIndex].Cells["outcome"].Value.ToString
If str = "Yes" Then
nb_myleads_dgv.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.DarkGreen
ElseIf str = "Pending" Then
nb_myleads_dgv.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.DarkOrange
ElseIf str = "No" Then
nb_myleads_dgv.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.DarkRed
End If

How to search in listview

I am trying to create a Loop that will read through the information on my ListView through the SubItem to find the text that matches the text in my Textbox whenever I hit the search button and Focuses the listbox onto the matched text. Below is what I have but it keeps telling me that the value of string cannot be converted. I am also pretty sure that my numbers wont loop correctly but I am not really sure how to cause them to loop endlessly till end of statement.
Dim T As String
T = Lines.Text
For r As Integer = 0 to -1
For C As Integer = 0 to -1
If List.Items(r).SubItems(C).Text = Lines.Text Then
List.FocusedItem = T
End If
Next
Next
End Sub
I don't understand your code, but I do understand the question. Below is example code to search all rows and columns of a listview. Search is case insensitive and supports a "find next match" scenario. If a match or partial match is found in any column the row is selected. TextBox1 gets the text to find. FindBtn starts a new search.
Private SrchParameter As String = ""
Private NxtStrtRow As Integer = 0
Private Sub FindBtn_Click(sender As Object, e As EventArgs) Handles FindBtn.Click
If Not String.IsNullOrWhiteSpace(TextBox1.Text) Then
SrchParameter = TextBox1.Text
NxtStrtRow = 0
SearchListView()
End If
End Sub
Private Sub ListView1_KeyDown(sender As Object, e As KeyEventArgs) Handles ListView1.KeyDown
If e.KeyCode = Keys.F3 Then
SearchListView()
End If
End Sub
Private Sub SearchListView()
' selects the row containing data matching the text parameter
' sets NxtStrtRow (a form level variable) value for a "find next match" scenario (press F3 key)
If ListView1.Items.Count > 0 Then
If SrchParameter <> "" Then
Dim thisRow As Integer = -1
For x As Integer = NxtStrtRow To ListView1.Items.Count - 1 ' each row
For y As Integer = 0 To ListView1.Columns.Count - 1 ' each column
If InStr(1, ListView1.Items(x).SubItems(y).Text.ToLower, SrchParameter.ToLower) > 0 Then
thisRow = x
NxtStrtRow = x + 1
Exit For
End If
Next
If thisRow > -1 Then Exit For
Next
If thisRow = -1 Then
MsgBox("Not found.")
NxtStrtRow = 0
TextBox1.SelectAll()
TextBox1.Select()
Else
' select the row, ensure its visible and set focus into the listview
ListView1.Items(thisRow).Selected = True
ListView1.Items(thisRow).EnsureVisible()
ListView1.Select()
End If
End If
End If
End Sub
Instead of looping like that through the ListView, try using a For Each instead:
searchstring as String = "test1b"
ListView1.SelectedIndices.Clear()
For Each lvi As ListViewItem In ListView1.Items
For Each lvisub As ListViewItem.ListViewSubItem In lvi.SubItems
If lvisub.Text = searchstring Then
ListView1.SelectedIndices.Add(lvi.Index)
Exit For
End If
Next
Next
ListView1.Focus()
This will select every item which has a text match in a subitem.
Don't put this code in a form load handler, it won't give the focus to the listview and the selected items won't show. Use a Button click handler instead.
This is the easiest way to search in listview and combobox controls in vb net
dim i as integer = cb_name.findstring(tb_name.text) 'findstring will return index
if i = -1 then
msgbox("Not found")
else
msgbox("Item found")
end if