DataGridView column order does not seem to work - vb.net

I have a DataGridView bound to a list of business objects:
Dim template As New IncidentTemplate
Dim temps As List(Of IncidentTemplate) = template.LoadAll
Dim bs As New BindingSource
If Not temps Is Nothing Then
bs.DataSource = temps
Me.dgvTemplates.DataSource = bs
End If
I then add an unbound button column and make some of the bound columns invisible:
Dim BtnCol As New DataGridViewButtonColumn
With BtnCol
.Name = "Edit"
.Text = "Edit"
.HeaderText = String.Empty
.ToolTipText = "Edit this Template"
.UseColumnTextForButtonValue = True
End With
.Columns.Add(BtnCol)
BtnCol = Nothing
For Each col As DataGridViewColumn In Me.dgvTemplates.Columns
Select Case col.Name
Case "Name"
col.DisplayIndex = 0
col.FillWeight = 100
col.Visible = True
Case "Description"
col.DisplayIndex = 1
col.FillWeight = 100
col.Visible = True
Case "Created"
col.DisplayIndex = 3
col.HeaderText = "Created On"
col.DefaultCellStyle.Format = "d"
col.FillWeight = 75
col.Visible = True
Case "CreatedBy"
col.DisplayIndex = 2
col.HeaderText = "Created By"
col.FillWeight = 75
col.Visible = True
Case "Edit"
col.DisplayIndex = 4
col.HeaderText = ""
col.FillWeight = 30
col.Visible = True
Case Else
col.Visible = False
End Select
Next
This seems to work reasonably well except no matter what I do the button column (Edit) always displays in the middle of the other columns instead of at the end. I've tried both DGV.Columns.Add and DGV.Columns.Insert as well as setting the DisplayIndex of the column (this works for all other columns) but I am unable to make the button column display in the correct location. I've also tried adding the button column both before and after setting the rest of the columns but this seems to make no difference Can anyone suggest what I am doing wrong? It's driving me crazy....

I stumbled on your post while looking to solve a similar problem. I finally tracked it down by doing as you mention (using the DisplayIndex property) and setting the AutoGenerateColumns property of the DataGridView to false. This property is not visible in the designer, so I just added it to the constructor for my form. Be sure to do this before setting the data source for your grid.
Hope this helps...

The AutoCreateColumn is the problem. The following article gives an example for how to fix it.
From DataDridView DisplayOrder Not Working
When setting the column’s DisplayIndex in a data grid view, some columns were out of order. To fix the issue, I had to set AutoGenerateColumns to true before setting the data source, and to FALSE after.
For Example:
dgvReservedStalls.AutoGenerateColumns = True
dgvReservedStalls.DataSource = clsReservedStalls.LoadDataTable()
dgvReservedStalls.AutoGenerateColumns = False

Same problem here, and after searching for a while, I found out that by setting the DisplayIndexes in Ascending order made it for me.
It's counter-intuitive, because it's a number, but I still had to set them in order.
This works:
With customersDataGridView
.Columns("ContactName").DisplayIndex = 0
.Columns("ContactTitle").DisplayIndex = 1
.Columns("City").DisplayIndex = 2
.Columns("Country").DisplayIndex = 3
.Columns("CompanyName").DisplayIndex = 4
End With
While this did not:
With customersDataGridView
.Columns("ContactName").DisplayIndex = 0
.Columns("CompanyName").DisplayIndex = 4
.Columns("Country").DisplayIndex = 3
.Columns("ContactTitle").DisplayIndex = 1
.Columns("City").DisplayIndex = 2
End With

I tried the above solutions without success. Then I found this article: It made it all better.
http://msdn.microsoft.com/en-us/library/vstudio/wkfe535h(v=vs.100).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1

Related

Cannot Hide Column in a DataGridView

I have four dgv's on a Winform. I successfully hid the unneeded columns on the first 3 dvg's by setting their "Visible" property to false. However, there is one column that will not hide on the fourth dgv and I cannot figure out why.
Here is the code for the fourth dgv:
With Me.DataGridView4
.DataSource = BSSJ
.AutoGenerateColumns = True
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
.Columns("RecID").Visible = False
.Columns("JobID").Visible = False
.Columns("Deleted").Visible = False
.Columns("Amt").DefaultCellStyle.Format = "#,##0.00"
.Columns("Amt").DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
End With
It is the "RecID" column that still appears in the dgv. The other two columns, "JobID" and "Deleted", are hidden as expected.
The data source, "BSSJ", is a bindingsource that is bound to an SQL table. I cannot omit this field from the Select statement of the query because it is needed in the relationship with the parent table.
The "RecID" is a primary key in the table bound to "BSSJ", but the other three dgv's have their primary key hidden successfully.
I'm probably missing something simple, but I just do not see it.
Any ideas?
This is not a direct answer as to why your code is not working, I could not replicate your issue.
But if you remove your autosizecolumns line of code, then you can set the width of the columns dynamically and potentially work around the issue
.Columns("RecID").Width = 0
.Columns("Amt").Width = 200
.Columns("JobID").Visible = False
.Columns("Deleted").Visible = False
.Columns("Amt").DefaultCellStyle.Format = "#,##0.00"
.Columns("Amt").DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight

check radiobutton according to the value of row item in dataset

I want to check radiobutton which is depends on value of specific row item in the dataset.
Dim adp As SqlDataAdapter = New SqlDataAdapter _
("select top 1 * from tbl_party_record order by rid desc", con)
Dim ds As DataSet = New DataSet()
adp.Fill(ds)
View.TextBox1.Text = ds.Tables(0).Rows(0).Item(1)
View.TextBox2.Text = ds.Tables(0).Rows(0).Item(2)
please consider item3 here as ds.Tables(0).Rows(0).Item(3).
If value of item3 is male then select radio button male elseif value of item3 is female then select radio button female elseif value of item3 is other then select radio button other.
how can I achieve this?
Thanks guys...
The logic is quite straightforward, I think. To set a radio button in ASP.NET you can use the Checked property:
'First un-check them all.
radiomale.Checked = False
radiofemale.Checked = False
radioother.Checked = False
'Now set the right one checked based on the data
Dim genderValue As String = ds.Tables(0).Rows(0).Item(2)
Select Case genderValue
Case "male"
radiomale.Checked = True
Case "female"
radiofemale.Checked = True
Case "other"
radioother.Checked = True
End Select
If you haven't already, you should also make sure all your radio buttons have the same value for the GroupName property, so that the user cannot select more than one radio button at the same time, and also so the value is posted back to the server properly on the next submit.

When loading from string to checked listview, the foreach skips characters

I have a string, My.settings.prohibitions, full of 1's and 0's; they correspond to which items of a checked listview should be checked and which should not. I tried using the following code to check items on the listview according to the values in the string, but it didn't work; the even numbered items were always unchecked, but the odd numbered items did get checked correctly.
For Each setting As Char In My.Settings.Prohibitions
If setting = "0" Then
ListView1.Items(My.Settings.Prohibitions.IndexOf(setting)).Checked = False
Else
ListView1.Items(My.Settings.Prohibitions.IndexOf(setting)).Checked = True
End If
Next
Edit: This does not work either:
Dim x As String = My.Settings.Prohibitions
For y As Integer = 0 To 7
If x(y).ToString = "1" Then
ListView1.Items(y).Checked = True
Else
ListView1.Items(y).Checked = False
End If
y += 1
Next
You need something like this:
For index As Integer = 0 To My.Settings.Prohibitions.Length - 1
ListView1.Items(index).Checked = My.Settings.Prohibitions(index) = "1"
Next

Listview help needed

I am confused being a relatively new user to vb.net. Why my listview is not amending the value in the list? If I may, so I have a correct working of how listview displays its data from database. I have a general question in addition to my code problem.
I have five columns in my listview (0-4). Am I correct in saying that if my access database contained say 10 fields but I only needed to display five of them but one of them was field (9), then would code the list like my code below, which is not changing the value and will only display the list if I remove the 'else' statement.
What is the error? Many thanks
UPDATED CODE:
oledbCnn.ConnectionString = My.Settings.storageConnectionString
oledbCnn.Open()
'drcount = Convert.ToInt32(dr("RowCount"))
sql = "Select TOP 100 * from Requests ORDER BY [Date-time received] DESC"
Debug.Print(sql)
Dim oledbCmd As OleDbCommand = New OleDbCommand(sql, oledbCnn)
Using dr = oledbCmd.ExecuteReader()
'clear items in the list before populating with new values
'lvRequests.Items.Clear()
While dr.Read()
If dr.HasRows Then
Dim LVI As New ListViewItem
With LVI
.Text = dr(0).ToString()
.UseItemStyleForSubItems = False
.SubItems.Add(CDate(dr(5)).ToShortDateString())
.SubItems.Add(dr(1).ToString())
.SubItems.Add(dr(3).ToString())
If dr(3).ToString = "D" Then
.SubItems(3).Text = "Destroyed"
ElseIf dr(3).ToString = "O" Then
.SubItems(3).Text = "Out"
ElseIf dr(3).ToString = "I" Then
.SubItems(3).Text = "Intake"
End If
.SubItems.Add(dr(9).ToString())
If dr(9).ToString = "DEMO" Then
.SubItems(9).Text = "Done"
End If
End With
lvRequests.Items.Add(LVI)
lvcount += 1
End If
End While
End Using
There is not enough info to be really sure what is going on. It appears that you pull 10 columns from the DB, but if you only post 5 of them to the LV, then there should only be 5 subitems. So this is wrong:
If dr(9).ToString() = "DEMO" Then
lvRequests.Items(lvRequests.Items.Count - 1).SubItems(9).Text = "Done"
' should probably be:
If dr(9).ToString() = "DEMO" Then
lvRequests.Items(lvRequests.Items.Count - 1).SubItems(4).Text = "Done"
What might make it clearer at least in code would be to use Names for the subitems. If you instance a SubItem object rather than use a default constructor, you can assign a name and reference them that way instead:
Dim si As New ListViewItem.ListViewSubItem
With si
.Text = dr(X).ToString ' dunno whats in there
' this is probably not exactly right, but give the SubItem
' the same name as the db column
.Name = dr.Table.Columns(X).ColumnName
End With
thisItem.SubItems.Add(si) ' add sub to Item collection
Now, your code can use the name rather than index:
If dr(9).ToString() = "DEMO" Then
lvReq.Items(lvReq.Items.Count - 1).SubItems("TheColumnName").Text = "Done"
it no longer really matters how many columns or subitems there are. The ListViewItem.SubItems collection does not require sub item names to be unique, so it is possible to end up with 2 with the same name, but if you map from the DR/DT/DB correctly, it should take care of itself.
If the LV is bound to the datasource (you did not say), then there could be as many SubItems as db/datasource columns (never actually used an LV that way).

datagridview and empty table

DataGridView1.DataSource = ds.Tables("Orders")
If the query returns no results (empty dataset table) I see -1 in first column of the DataGridView in OrderID column. When I click on a grid columns header it decreases -2, -3 etc.
How to fix it?
How about:
If ds.Tables("Orders").Rows.Count = 0 Then
lblNoResults.Visible = True
DataGridView1.Visible = False
Else
lblNoResults.Visible = False
DataGridView1.DataSource = ds.Tables("Orders")
'Anything else you need to do
DataGridView1.Visible = True
End If
lblNoResults would be a label with text something like "No results found" that you would display instead of your DataGridView.
Basically, don't bind the datasource if there are no rows in it.
It might be that there are bugs in your other code causing your specific problem. If you want to show more of your code then it'll be easier to say what's going wrong.