DataGridView DataSource // integer to icon - vb.net

I've got a list-based application that runs very slow, because each row in my DataGridView is build manually as DataGridViewRow. To fix performance issues i decided to use a DataSource (DataTable) instead.
My problem:
One column I am recieving from my database is filled with image IDs. The application knows which image belongs to which id. When creating gridrows manually there was no problem in translating int to a bitmap and use the bitmap as value for an imagecolumn. Now using the Datatable instead i cant get it working. For testing i wrote the following class:
Public Class test
Dim img As Bitmap
Public Sub New(image As Bitmap)
InitializeComponent()
Me.img = image
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dt As New DataTable
dt.Columns.Add("StrCol")
dt.Columns.Add("ImgCol")
Dim row As DataRow = dt.NewRow
row.Item(0) = "Ohne Bild"
row.Item(1) = 0
Dim row2 As DataRow = dt.NewRow
row2.Item(0) = "Mit Bild"
row2.Item(1) = 1
dt.Rows.Add(row)
dt.Rows.Add(row2)
DataGridView1.DataSource = dt
End Sub
Private Sub DataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
If e.ColumnIndex = 1 Then
If e.Value = 0 Then
e.Value = Nothing
Else
e.Value = img
End If
End If
End Sub
End Class
hint:
"Ohne Bild" translates into "Without image"
"Mit Bild" translates into "With image"
Output after Button1_Click()
EDIT
Due to a missunderstanding I will try to clarify my question;
By list-based i dont actually mean the list-object. My bad there.By list-based i mean an application that displays the user Database entrys he made. The very basic of my application is simple: Allow user to add Rows, Edit and delete rows in a datagridview. This information is saved and edited in a database. Some of these informations in the rows (2 columns to be exactly) are displayed as icons while the application simply saved an id for the icon in the database. So the application knows which ID belongs to which icon.
The sample dt in the question is just to have something to work with. In the application it will be data recieved from a database to a datatable.

I finally solved it myself.
I get a datatable from my database.
Then I add a Column to it with the DataType Bitmap
Then I loop through each row of the DataTable and translate the Image_ID column to the image itself and put the image into the new Column
Then I remove the Image_ID column
Then I use the new DataTable as DataSource
I created that code in my main application which is a lot more complex so I can't show the code here. Sorry for that and thanks for your help.
It is important to do every change you need to do before using the table as source, because as soon as the gridView has to change something that is displayed it takes a lot more time.

Related

Autofill TextBox/Checkbox from a previous TextBox' value (VB.NET Database)

Note: I'm using Visual Studio, original work was on SQL Server, moved to VB.NET
I have a Textbox "ViewStatusTxt", next to it there's a Button "ViewStatusBtn"
Below it there's a TextBox "ViewNAMETxt", another TextBox "ViewACTIVITYTxt" and then a Checkbox "ModifyStatusCB"
I'm trying to auto-fill the Checkbox AND the Textbox based on the ID input there, however I really have no clue about it since I'm new to VB.NET
Here's the code used
Private Sub IDSearch(StatusViewBtn As String)
' ADD SEARCH QUERY PARAMETERS - WITH WILDCARDS
SQL.AddParam("#StatusViewBtn", StatusViewBtn)
'RUN QUERY - SEARCH GIVES THOSE RESULTS
SQL.ExecQuery(" SELECT
aID,
Name,
Status,
Activity
FROM
[dbo].[initialTable]
WHERE
aID = #StatusViewBtn
ORDER BY
aID ASC")
End Sub
That's the function's code, which is fully working since it's a smaller version of the same one I used in a Search Page
Here's the button's function, which I'm sure is where I'm having problems, unless I need to add a specific function to the ViewNAMETxt
Private Sub StatusViewBtn_Click(sender As Object, e As EventArgs) Handles StatusViewBtn.Click
IDSearch(StatusViewBtn.Text)
ViewNAMETxt.Text = SQL.ExecQuery("SELECT
Name
FROM
initialTable
WHERE
aID = #StatusViewBtn")
End Sub
And I haven't even started on the Checkbox, viewing how the first one caused me issues. Hopefully the solution would be similar to both of them.
Thanks for reading guys, and sorry for the newbie question
1- Suppose you have a table named YourTable(int KeyColumn, string StringColumn, boolean BooleanColumn)
2- Create a form and put 2 textboxes and a checkbox and a button on it. KeyColumnTextBox, StringColumnTextBox, BooelanColumnCheckBox, SearchButton
3- In click event handler for SearchButton put the codes:
Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click
Dim connection = New SqlConnection("Your Connection string here")
Dim command = New SqlCommand("SELECT StringColumn, BooleanColumn FROM YourTable WHERE KeyColumn=#KeyColumn", connection)
command.Parameters.Add(New SqlParameter("#KeyColumn", Int32.Parse(KeyColumnTextBox.Text)))
connection.Open()
Dim reader = command.ExecuteReader()
While reader.Read()
StringColumnTextBox.Text = reader.GetString(0)
BooleanColumnCheckBox.Checked = reader.GetBoolean(1)
End While
End Sub
Don't forget to Imports System.Data.SqlClient at top of your file.

Reading txt file line by line in DataGrid View

I'm completely new to VB.net and have been given a homework assignment. I need to be able to read certain lines and display them in a DataGridView. I have been able to link my .txt file to the DGV however it reads the whole file as opposed to the specific line. I have 4 buttons: btn1, btn2, btn3, btn4. I want each button to show the respective lines in the text file. After researching on-line for the past week I'm still stuck. If anyone could help me I would really appreciate it.
Text File ("database.txt")
(Line1) c1 c2 c3
(Line2) one 1-1 1-2
(Line3) two 2-2 2-3
(Line4) three 3-2 3-3
(Line5) four 4-2 4-3
Public Class Form1
Private Sub btn1_Click(sender As Object, e As EventArgs) Handles btn1.Click
Dim lines = (From line In IO.File.ReadAllLines("database.txt") _
Select line.Split(CChar(vbTab))).ToArray
For x As Integer = 0 To lines(0).GetUpperBound(0)
DataGridView1.Columns.Add(lines(0)(x), lines(0)(x))
Next
For x As Integer = 1 To lines.GetUpperBound(0)
DataGridView1.Rows.Add(lines(x))
Next
End Sub
End Class
You did not describe the result you get, so I cannot tell what's wrong right now, as I am not on a computer and usually use c++/cli (visual c++). If I have to make a guess, I would say that you fill each file row into one DGV row, but you want just 1 row, not all. Correct?
Anyway, here are some suggestions:
Do you have to read the file on each button click? If not, I would read it once, store the content and fill into the DGV when desired.
Debug your code! Set a breakpoint at the start of the function, step over the code lines, check the variable content.
Split up the code line dim lines into 3 or more separate lines to make it more readable. Also helps at debugging.
I made following assumptions based on what you had in your question:
First line of the file was the column names
The (Line#) was just there for reference and isn't in the actual file
The number in the button name (btn#) was the row index that should be displayed in the DGV
I added a new button to the form that loads the data from the text file, parses it to a datatable and sets the DataGridView1.DataSource to that DataTable. The second method then creates a new datatable and imports the specified row from the main datatable and shows it in the DGV. Of course many will say you should use a DataView with a DataView.RowFilter for this rather than creating a new datatable, however this way works just the same.
Private txtDataTable As DataTable
Private Sub loadFileBtn_Click(sender As Object, e As EventArgs) Handles loadFileBtn.Click
txtDataTable = New DataTable("txtContents")
Dim txtContents As String()
Try
txtContents = IO.File.ReadAllLines("C:\StackOverflow\database.txt")
Catch ex As Exception
MsgBox(ex.Message)
Return
End Try
Dim txtLines As New List(Of String())
txtContents.ToList().ForEach(Sub(x) txtLines.Add(x.Split(CChar(vbTab))))
If txtLines.Count > 0 Then
txtLines.Item(0).ToList.ForEach(Sub(x) txtDataTable.Columns.Add(New DataColumn(x.ToString)))
txtLines.RemoveAt(0)
End If
If txtLines.Count > 0 Then
txtLines.ToList.ForEach(Sub(x) txtDataTable.Rows.Add(x.ToArray))
End If
DataGridView1.DataSource = txtDataTable
End Sub
Private Sub btn_Click(sender As Object, e As EventArgs) Handles btn1.Click, btn2.Click, btn3.Click, btn4.Click
If txtDataTable Is Nothing Then Return
Dim rowIndex As Integer
If Integer.TryParse(DirectCast(sender, Button).Name.Replace("btn", String.Empty), rowIndex) Then
rowIndex -= 1
Else
Return
End If
Dim TempTable As DataTable = txtDataTable.Clone
If rowIndex < txtDataTable.Rows.Count Then
TempTable.ImportRow(txtDataTable.Rows(rowIndex))
End If
DataGridView1.DataSource = TempTable
End Sub

how to update, insert records through datagridview to sql using data adapter or other method in vb.net

hello best programmers in the world i need your expert advise and assistance with regards to my project.
I am trying to insert and update my table through datagridview by clicking a command button,
i have my datagridview properties set to editmode : editprogrammatically,
here's the code, of where i pulled up my datagridview content:
Public Sub loaddgvfrm3()
cmdconn = New SqlConnection
cmd = New SqlCommand
cmdconn.ConnectionString = sqlstr
cmdconn.Open()
cmd.Connection = cmdconn
cmd.CommandText = "select period, VOUCH_AMT, INDIVIDUAL_AMT, check_no, D_MAILED, DIR_NO from tobee.EBD_BILLHISTORY where CLAIM_NO like '" + txtClaimno.Text + "'"
Dim dt As New DataTable
da = New SqlDataAdapter
da.SelectCommand = cmd
da.Fill(dt)
Me.DataGridView1.DataSource = dt
Me.DataGridView2.DataSource = dt
cmdconn.Close()
End Sub
now i have my command buttons here
here's the add button: (im prefering to add a row within the selected table)
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
End Sub
here's the Edit button:
Private Sub btnEditmain_Click(sender As Object, e As EventArgs) Handles btnEditmain.Click
''Form1.ShowDialog()
'DataGridView2.AllowUserToAddRows = True
''DataGridView2.BeginEdit(True)
'btnSave.Enabled = True
End Sub
and here's the save button that should save all changes that i have done,
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim connstr As String = "server=midtelephone\sqlexpress; database=testdb; user= sa; password=sa;"
End Sub
i left command button contents empty because i need to create a new method of inserting, updating the row. because the one that i have earlier was a fail, although it inserts the data in the sql, but not in its appropriate row, take a look at here: Data inserted from datagridview not updated in SQL Server , instead it creates another row which is not connected with '" + txtClaimno.Text + "'" (stated from above) so what happens is that it stacks a new row with no connected owner from another table(claim_no < this claim_no is connected from another table as a fk in the database but a primary key in (billhistory table))
can you pls help me get rid of this problem as i am having a hard time moving to the next phase of our project? im just a high school student, so pls bear with me :) i'll appreciate if u give comments / answers regarding my question :) thanks in adv.
my mentor advised me to use data adapter accept changes stuff, but i don't know how to implement such stuffs. pls help me thank you :)
Use Event to get data from gridview on cellConttent Click and these values to a query or Stored procedure.
private void grdCampaignStats_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
//I want to get value of SomeColumn of grid view having datatype String
string SomeVariabel = grd["CoulmnNameinGRID", e.RowIndex].Value.ToString();
// Make it according to Vb it is C# code
}

How to add a row to a datatable?

I face a stupid problem here. Cannot find an error and do not really know how to fix this.
I'm adding an item into datatable on selected index changed. Everything works, except only the last item is shown in dt. I always has the latest item and all others are gone. i suppose this is because I initialize it in the wrong place but still cannot find a solution.
Dim dt As DataTable = New DataTable()
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Page.Load
dt.Columns.Add("dr1")
dt.Columns.Add("dr2")
End Sub
Protected Sub ddlTest_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles ddlTest.SelectedIndexChanged
Dim row As DataRow = dt.NewRow()
row(0) = "Test!"
row(1) ="Test"
dt.Rows.Add(row)
End If
End Sub
This always shows only last item in list. How do I do this correct way?
Unless I am mistaken, you create a new DataTable every time a user hits the page.
You need to persist the row to a real database or perhaps make your DataTable shared (static in C#) instead.
Shared dt As DataTable = New DataTable()

Random browsing of images (animated)

I was trying to make a program that shows picture in a folder.
The path of each picture was stored in the database.
My problem was it only show the last images stored in the database and not all the pictures.
The code is:
Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
Dim ctr As Integer = 0
Dim pic As String
Dim sqlconn As New SqlConnection("data source=NMPI_2;initial catalog=IPCS; " & _
"password=rhyatco; " & _
"persist security info=True; " & _
"user id= rhyatco;" & _
"packet size=4096")
sqlconn.Open()
Dim query As String = "Select picture from Bpicture"
Dim sqlcomm As New SqlCommand(query, sqlconn)
Dim reader As SqlDataReader
reader = sqlcomm.ExecuteReader
While reader.Read
pic = reader("picture").ToString
Me.PictureBox1.Image = Image.FromFile(pic)
Me.PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End While
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
It's always going to show the last image, because you are retrieving the entire table and retrieving all the records with the While loop. The last image will always be the winner.
There are two possible solutions:
One, randomly retrieve one image from the database. Check this stackoverflow thread on how to randomly select a row. The caveat with this solution is you make a call to the database every time.
Two, retrieve all the images from the database, store the data in a collection and randomly select one of the images from the collection. The caveat with this solution is there maybe too many images to store in a collection in memory, in which case you have to go with One.
Well the problem that I see with what you've provided is that you're running the query and iterating through all the rows in the result set every time the timer fires.
I think what you're really looking for is to download the result set once when the form loads, and then to switch which picture you're looking at on the timer.
One way to just rotate through them all over and over again would be to download the list and populate them into a Queue of filenames, and then on the timer just do something like this (sorry, my example is in C#):
string fileName = imageFileNameQueue.Dequeue();
PictureBox1.Image = Image.FromFile(fileName);
imageFileNameQueue.Enqueue (fileName); // Put the file back at the back of the queue
A simple change to your existing solution that will kind of work is to break out of the while loop with some probability. A problem with this solution is that images later in the query result are much less likely to be shown than earlier images.
I haven't done any VB so I'm coding via Google, but you'll need to create an instance of Random somewhere:
Dim rand as new Random()
Then in your while loop, pull off a random number to see if you should stop:
While reader.Read
...
If rand.Next(10) > 8 Then
Exit While
End If
End While
EDIT: You should also move the code to set the Image and SizeMode out of the while loop so that they're only set one time, once you've decided on the image.