vb.net - button.text not aligning when pulled from data table - sql

Please refer to the images below:
So the left image has a hardcoded string and the image on the right has the data pulled in form an MSSQL database.
The code below makes up these buttons (they are dynamically created based on the amount of records in the database table)
'Button
Private Sub LoadUseraccount()
'Connect to Database (from module1)
connectSQL()
'Setup DataAdapter with query
Dim da As SqlDataAdapter
da = New SqlDataAdapter("SELECT * from useraccounts", SQLConn)
'Store results in temporary datatable
Dim dt As DataTable
dt = New DataTable()
da.Fill(dt)
Dim i As Integer
'Create a button for every record shown in useraccount table.
For i = 0 To dt.Rows.Count - 1
Dim dr As DataRow = dt.Rows(i)
Dim newbutton As New Windows.Forms.Button
Dim dataString As String = CStr(dr.Item("username"))
newbutton.Name = "btnButton" & i
newbutton.Text = dataString '<========= This Line is where the button text is set
newbutton.Top = 200 + i * 105
newbutton.Left = 40
newbutton.TextAlign = ContentAlignment.MiddleCenter
newbutton.Height = 107
newbutton.Width = 180
Dim myFont As System.Drawing.Font
myFont = New System.Drawing.Font("Arial", 20.25)
newbutton.Font = myFont
newbutton.ForeColor = Color.White
newbutton.BackColor = Color.MidnightBlue
Me.Controls.Add(newbutton)
Next
SQLConn.Close()
End Sub
So the only difference in the images is what the text is set to display on the buttons, but the alignment is all out of whack when the string is not static.
What am I doing wrong or what am I missing to have the right image formatted the same as the left one?
Cheers :-)

I have tried your example and I was unable to reproduce the problem until I added a carriagereturn/linefeed to the variable used for button text.
So I assume that your data contains some unprintable characters that disalign your output.
A simple fix should be
newbutton.Text = dataString.Trim()

Related

Display image from filename in a database record to a datagridview

I want to display the picture found in the file location that is in the field "Picture" I have this code that shows the fields in the datagridview but I cannot figure how to properly code image from file.
Update - this below code works fine
enter code here
Imports System.Data.OleDb
Public Class test
Dim ds As New DataSet
Dim dt As New DataTable
Dim da As New OleDbDataAdapter
Private Sub test_Load(sender As Object, e As EventArgs) Handles MyBase.Load
getthedata() ' this does a query and adds a column to the query data datatable
Filldatagrid() ' This fills the datagridview named DG1
End Sub
Sub getthedata()
sel = "select * from dog"
DataConnection()
cmd = New OleDbCommand(sel, con)
ds.Tables.Add(dt)
da = New OleDbDataAdapter(cmd)
da.Fill(dt)
Dim imageColumn As New DataColumn
imageColumn.ColumnName = "Picture"
imageColumn.DataType = GetType(System.Drawing.Image)
dt.Columns.Add(imageColumn)
For Each row As DataRow In dt.Rows
row("Picture") = System.Drawing.Image.FromFile(row("pic"))
Next
dt.AcceptChanges()
con.Close()
End Sub
Sub Filldatagrid()
dg1.AutoGenerateColumns = False
dg1.RowTemplate.Height = 150 ' this is the larger size to accomodate the image
dg1.ColumnCount = 4
dg1.DataSource = dt
dg1.Columns(0).DataPropertyName = "ID"
dg1.Columns(0).Visible = False
dg1.Columns(1).HeaderText = "Name"
dg1.Columns(1).DefaultCellStyle.Font = New Font("Tahoma", 15)
dg1.Columns(1).DefaultCellStyle.ForeColor = Color.DarkGreen
dg1.Columns(1).DataPropertyName = "Nam"
dg1.Columns(1).Width = 100
dg1.Columns(2).HeaderText = "Birthday"
dg1.Columns(2).DefaultCellStyle.Font = New Font("Tahoma", 15)
dg1.Columns(2).DataPropertyName = "Birth"
dg1.Columns(2).Width = 150
dg1.Columns(3).DataPropertyName = "Pic"
dg1.Columns(3).Visible = False
Dim dgvImageColumn As New DataGridViewImageColumn
dgvImageColumn.DataPropertyName = "Picture"
dgvImageColumn.Width = 150
dgvImageColumn.ImageLayout = DataGridViewImageCellLayout.Zoom
dg1.Columns.Add(dgvImageColumn)
End Sub
End Class
The database records are:
Id Nam Birth Pic Comments
1 Brody 5/15/2015 C:\Users\JRS89\Dropbox\Photos\dogs\Brody\Brody.jpg
2 Bella 5/1/2015 C:\Users\JRS89\Dropbox\Photos\dogs\Bella\Bella.jpg
3 Benji 5/15/2016 C:\Users\JRS89\Dropbox\Photos\dogs\Benji\Benji.jpg

DataGridView moves rows to bottom when cell is updated with Unbound data

I have a DataGridView that is styled with code and is using data from a SQLite Database
The Database is NOT bound to the DataGridView. A number of events are triggered when I click on a row.
First the Database is updated with today's date.
And the cell that contain's that date reflects the change.
I then call a sort on the column based on the cells value. With this code
dgvLinks.Sort(dgvLinks.Columns(3), ListSortDirection.Ascending)
The process works as expected with no issues IF I omit these lines of code from the Sub Routine ViewSearches() that populates the DataGridView.
If rowCount <= 25 Then
maxRowCount = 25 - rowCount
For iA = 1 To maxRowCount
dgvLinks.Rows.Add(" ")
Next
End If
I can use these empty rows if I make a call to repopulate the DataGridView with ViewSearches()
I am trying to avoid this design as it seems like a over use of resource.
The ERROR that is happening is the 4 rows that contain data are moved to the bottom of the DataGridView and above these 4 rows with data are the empty rows. I will post the relevant code below.
My question How can I keep the empty rows and populate DataGridView so the rows with data are at the top of the DataGridView?
Here is a Screen Shot after I selected LID 2. It is updated and bubbled to the bottom of the DGV.
Private Sub ViewSearches()
Dim intID As Integer
Dim strChannelName As String
Dim strLinkAddress As String
Dim strLastVisit As String
Dim strLinkType As String
Dim rowCount As Integer
Dim maxRowCount As Integer
'Dim emptyStr As String = " "
Using conn As New SQLiteConnection($"Data Source = '{gv_dbName}';Version=3;")
conn.Open()
Using cmd As New SQLiteCommand("", conn)
'cmd.CommandText = "SELECT * FROM LinkTable"
' Line of CODE Above works with If statement in While rdr
'==========================================================
'cmd.CommandText = "SELECT * FROM LinkTable WHERE ytSiteType = 'News'"
cmd.CommandText = "SELECT * FROM LinkTable WHERE ytSiteType = #site"
cmd.Parameters.Add("#site", DbType.String).Value = gvSLT
Using rdr As SQLite.SQLiteDataReader = cmd.ExecuteReader
'dgvLinks.DataSource = rdr
'Statement Above use when DB is bound to dgvLinks
'=================================================
While rdr.Read()
intID = CInt((rdr("LID")))
strChannelName = rdr("ytChannelName").ToString
strLinkAddress = rdr("ytLinkAddress").ToString
strLastVisit = rdr("ytLastVisit").ToString
strLinkType = rdr("ytSiteType").ToString
'If strLinkType = gvSLT Then
dgvLinks.Rows.Add(intID, strChannelName, strLinkAddress, strLastVisit)
rowCount = rowCount + 1
'End If
End While
dgvLinks.Sort(dgvLinks.Columns(3), ListSortDirection.Ascending)
End Using
If rowCount <= 25 Then
maxRowCount = 25 - rowCount
For iA = 1 To maxRowCount
dgvLinks.Rows.Add(" ")
Next
End If
End Using
End Using
'FindEmpty()
End Sub
Click Event with Update to Database
Private Sub dgvLinks_CellClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvLinks.CellClick
selRow = e.RowIndex
If e.RowIndex = -1 Then
gvalertType = "4"
frmAlert.ShowDialog()
Exit Sub
End If
'Dim col As DataGridViewColumn = Me.dgvLinks.Columns(e.ColumnIndex)
Dim row As DataGridViewRow = Me.dgvLinks.Rows(e.RowIndex)
If row.Cells(2).Value Is Nothing Then
gvalertType = "5"
frmAlert.ShowDialog()
Return
Exit Sub
ElseIf gvTxType = "View" Then
webPAGE = row.Cells(2).Value.ToString()
siteID = CInt(row.Cells(0).Value.ToString())
UpdateSiteData()
''MsgBox("Stop " & selRow)
'dgvLinks.ClearSelection()
'dgvLinks.Refresh()
'dgvLinks.RefreshEdit()
Process.Start(webPAGE)
'dgvLinks.Columns.Clear()
''dgvLinks.Rows.Clear()
''ViewSearches()
ElseIf gvTxType = "Delete" Or gvTxType = "Update" Then
gvID = CInt(row.Cells(0).Value)
gvSiteName = row.Cells(1).Value.ToString
gvSiteURL = row.Cells(2).Value.ToString
frmADE.Show()
Close()
End If
End Sub
Update Routine
Public Sub UpdateSiteData()
Dim dateToday = Date.Today
dateToday = CDate(CDate(Date.Today).ToString("M-d-yyyy"))
Using conn As New SQLiteConnection($"Data Source = '{gv_dbName}';Version=3;"),
cmd As New SQLiteCommand("UPDATE LinkTable SET ytLastVisit = #ytLastVisit WHERE LID =" & siteID, conn)
conn.Open()
cmd.Parameters.Add("#ytLastVisit", DbType.String).Value = dateToday.ToString("M-d-yyyy")
cmd.ExecuteNonQuery()
dgvLinks.Rows(selRow).Cells(3).Value = dateToday.ToString("M-d-yyyy")
'Line of code above INSERTS value in Last Visit Column at the correct ROW
'NOT needed if you reload data from the database
'=========================================================================
'dgvLinks.Refresh()
'dgvLinks.RefreshEdit()
dgvLinks.Sort(dgvLinks.Columns(3), ListSortDirection.Ascending)
End Using
End Sub
You will see a number of things I have tried commented out.
As I said I can FIX the issue if I make a call to the ViewSearches() Sub Routine.
Private Sub StyleDGV()
'Sets Design of the DataGridView
'===============================
dgvLinks.DefaultCellStyle.Font = New Font("Times New Roman", 13.0F, FontStyle.Bold)
dgvLinks.ColumnCount = 4
dgvLinks.Columns(0).Width = 60 'ID
dgvLinks.Columns(1).Width = 325 'Site Name 325
dgvLinks.Columns(2).Width = 860 'Site Url 860
dgvLinks.Columns(3).Width = 154 'LastVisit 140
'Option with no blank rows increase col count to 5
'OR increase width of col(3) WHY? because the scroll bar is not showing
' TOTAL Width 1450 Height 488
'=============================
'To Set Col Header Size Mode = Enabled
'To Set Col Header Default Cell Styles DO in Properties
'dgvLinks.Columns(6).DefaultCellStyle.Format = "c"
dgvLinks.ColumnHeadersHeight = 10 'Sans Serif 'Tahoma
dgvLinks.ColumnHeadersDefaultCellStyle.Font = New Font("Sans Serif", 12.0F, FontStyle.Bold)
dgvLinks.ColumnHeadersDefaultCellStyle.ForeColor = Color.Blue
dgvLinks.DefaultCellStyle.BackColor = Color.LightGoldenrodYellow
'DGV Header Names
dgvLinks.Columns(0).Name = "LID"
dgvLinks.Columns(1).Name = "Site Name"
dgvLinks.Columns(2).Name = "Site URL"
dgvLinks.Columns(3).Name = "Last Visit"
dgvLinks.Columns(0).SortMode = DataGridViewColumnSortMode.NotSortable
dgvLinks.Columns(1).SortMode = DataGridViewColumnSortMode.NotSortable
dgvLinks.Columns(2).SortMode = DataGridViewColumnSortMode.NotSortable
dgvLinks.Columns(3).SortMode = DataGridViewColumnSortMode.NotSortable
End Sub
Any one following this question the FIX that permitted keeping the empty rows was to just omit the sort command in the Update to Database Sub Routine
As far as getting the data from the SQLite DB into the grid… you almost have it in the ViewSearches method. The command text looks good; however you are using an SQLiteDataReader. This is resorting to reading the data line by line.
I suggest you use the SQLiteDataAdapter instead. With it you can get the DataTable from the DB in one shot. First create and initialize a DataSet, then create a new SQLiteDataAdapter then add your command to the data adapter something like…
DataSet ds = new DataSet();
using (SQLiteDataAdapter sqlDA = new SQLiteDataAdapter()) {
conn.Open();
sqlDA.SelectCommand = cmd.CommanText;
sqlDA.Fill(ds, “tableName”);
if (ds.Tables.Count > 0) {
//return ds.Tables[“tableName”];
dgvLinks.DataSource = ds.Tables[“tableName”];
}
}
This will add a DataTable to the DataSet ds called “tableName” if the query succeeded.
Then simply use that DataTable as a DataSource to the grid… something like…
dgvLinks.DataSource = ds.Tables[“tableName”];

Display image in Datagridview

I am trying to display image in datagridview using ms-access and vb.net 2012.
my database in store image path does not image directly so when try to retrieve image in datagridview it shows the image path, not the image.
so how can I fix it?
Private Sub design_list_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'Design_managementDataSet.design_details' table. You can move, or remove it, as needed.
'Me.Design_detailsTableAdapter.Fill(Me.Design_managementDataSet.design_details)
cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\Design Management\Database\design_management.accdb"
If Not cnn.State = ConnectionState.Open Then
cnn.Open()
End If
designDatagridShow()
End Sub
Private Sub designDatagridShow()
Dim ds As New DataSet
Dim dt As New DataTable
ds.Tables.Add(dt)
Dim da As New OleDbDataAdapter
da = New OleDbDataAdapter("select * from design_details", cnn)
da.Fill(dt)
design_datagridview.AutoGenerateColumns = False
Dim ColImage As New DataGridViewImageColumn
Dim Img As New DataGridViewImageCell
design_datagridview.ColumnCount = 3
design_datagridview.Columns(0).Name = "design_number"
design_datagridview.Columns(0).HeaderText = "Design Number"
design_datagridview.Columns(0).DataPropertyName = "design_number"
design_datagridview.Columns(1).Name = "design_collection"
design_datagridview.Columns(1).HeaderText = "Design Collection"
design_datagridview.Columns(1).DataPropertyName = "design_collection"
design_datagridview.Columns(2).Name = "price"
design_datagridview.Columns(2).HeaderText = "Design Price"
design_datagridview.Columns(2).DataPropertyName = "price"
design_datagridview.Columns(3).Name = "design_image"
design_datagridview.Columns(3).HeaderText = "Design Image"
design_datagridview.Columns(3).DataPropertyName = "design_image"
design_datagridview.DataSource = dt
Dim value As String
value = design_datagridview.Columns(3).HeaderText = "design_image"
Label1.Text = value
cnn.Close()
End Sub
Update 1:
Thanks.
Add another column that is of System.Drawing.Image datatype, then set the image based on your image column's path using System.Drawing.Image.FromFile(...) like the following:
Dim imageColumn As New DataColumn
imageColumn.ColumnName = "ActualImage"
imageColumn.DataType = GetType(System.Drawing.Image)
dt.Columns.Add(ImageColumn)
For Each row As DataRow in dt.Rows
row("ActualImage") = System.Drawing.Image.FromFile(row("design_image"))
Next
dt.AcceptChanges()
Dim dgvImageColumn As New DataGridViewImageColumn
dgvImageColumn.DataPropertyName = "ActualImage"
dgvImageColumn.Name = "ActualImage"
dgvImageColumn.ImageLayout = DataGridViewImageCellLayout.Zoom
design_datagridview.Columns.Add(dgvImageColumn)
design_datagridview.DataSource = dt

datagridview Image Display vb.net MS Access

my code is to read the image file path in every row and display it in the datagridview "Image" Column.
.....
what's the problem with my code? please help me fix this.
UPDATE
this is the updated code but it displays nothing.
Dim dbdataset As New DataTable
Try
con.Open()
query = "Select * FROM [svfmemberlist]"
cmd = New OleDbCommand(query, con)
da.SelectCommand = cmd
da.Fill(dbdataset)
dgvSearch.RowTemplate.Height = 150
source.DataSource = dbdataset
dgvSearch.DataSource = source
Dim img As New DataGridViewImageColumn()
dgvSearch.Columns.Add(img)
img.HeaderText = "Image"
img.Name = "img"
img.ImageLayout = DataGridViewImageCellLayout.Zoom
dgvSearch.Columns("img").DataGridView.AutoGenerateColumns = False
dgvSearch.Columns("Name").AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
dgvSearch.Columns("img").Width = 150
For Each row As DataGridViewRow In dgvSearch.Rows
If Not row.Cells("imgPath").FormattedValue.ToString = Nothing Then
Dim str As String = row.Cells("imgPath").FormattedValue.ToString
Dim inImg As Image = Image.FromFile(str)
row.Cells("img").Value = inImg
Else
img.Image = Nothing
End If
Next
con.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
The following example does not match how you are loading data and images but with a little effort will work within your current code.
I created two columns in the DataGridView via the IDE, one Text and one Image DataGridViewColumn.
The first line in form load sets ImageLayout, second line of code sets alignment to top-left for appearances. Next I set auto-size mode for all columns followed by setting the row height for each row.
Next (these lines are to load images from a folder one level below the app folder).
Setup the path to the images.
Add images using FileImageBytes function (which I would place into a separate class or code module but works just fine in your form).
Yes everything is hard-wired so it's easy to see how everything works.
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CType(DataGridView1.Columns("PictureColumn"), DataGridViewImageColumn).ImageLayout = DataGridViewImageCellLayout.Normal
DataGridView1.Columns.Cast(Of DataGridViewColumn).Select(Function(col) col).ToList _
.ForEach(Sub(col) col.CellTemplate.Style.Alignment = DataGridViewContentAlignment.TopLeft)
DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
DataGridView1.RowTemplate.Height = 222
Dim imagePath As String = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images")
DataGridView1.Rows.Add(New Object() {"Car1", FileImageBytes(IO.Path.Combine(imagePath, "Car1.bmp"))})
DataGridView1.Rows.Add(New Object() {"Car2", FileImageBytes(IO.Path.Combine(imagePath, "Car2.jpg"))})
End Sub
Public Function FileImageBytes(ByVal FileName As String) As Byte()
Dim fileStream As IO.FileStream = New IO.FileStream(FileName, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Dim byteArray(CInt(fileStream.Length - 1)) As Byte
fileStream.Read(byteArray, 0, CInt(fileStream.Length))
Return byteArray
End Function
End Class

Datagridview CheckboxColumn Shaded or (X) Mark when unchecked

Good Morning
I have a column in DataGridView that generates checkbox and in relation to that I have also a lot of columns in my table that is called 2016,2017 and so on and all of that is TinyInt
Now here is the image for both of them:
Now here is my question, instead of uncheck how can make it shaded or X mark in the DataGridView Column?
here is my code in populating the DataGridView:
Dim sql1 As MySqlCommand = New MySqlCommand("Select * from period_closure", con1)
Dim ds1 As DataSet = New DataSet
Dim adapter1 As MySqlDataAdapter = New MySqlDataAdapter
con1.Open()
adapter1.SelectCommand = sql1
adapter1.Fill(ds1, "MyTable")
DataGridView1.DataSource = ds1.Tables(0)
con1.Close()
ds1.Tables(0).Columns(2).DataType = GetType(Boolean)
Me.DataGridView1.Columns(0).Frozen = True
Dim i As Integer
For i = 0 To DataGridView1.Columns.Count - 1
DataGridView1.Columns.Item(i).SortMode = DataGridViewColumnSortMode.Programmatic
Next
DataGridView1.Columns("PeriodID").Visible = False
DataGridView1.Columns(0).DefaultCellStyle.BackColor = Color.LightBlue
First of all download 'X' image in google, or create your own.
then try to add this in your code.
Private Sub CheckBox1_Paint(sender As Object, e As PaintEventArgs) Handles CheckBox1.Paint
If CheckBox1.Checked = False Then
Try
Dim newImage As Image = Image.FromFile("E:\Projects\Library\BER-X.jpg")
Dim x As Single = 0
Dim y As Single = 0
Dim width As Single = CheckBox1.Width 'You can also try this CheckBox1.Width - 3
Dim height As Single = CheckBox1.Height 'You can also try this CheckBox1.Height - 3
e.Graphics.DrawImage(newImage, x, y, width, height)
Catch ex As Exception
End Try
End If
End Sub
the X mark in the checkbox is not accurate in the position but you can fix it by your self. Try it and Explore it to fit it in your system. :)
Hope this will help you.