Welcome Guest! To access all forums & features, please register an account or sign-in. → Why register?



Formatting a listview item


9 replies to this topic - - - - -

#1 +Daedroth

    Resident Fanatic

  • 941 posts
  • Joined: 15-June 11
  • Location: UK

Posted 23 February 2012 - 14:24

Hey people!

I have pulled information from an access table into a listview item within Visual Basic 2010. It displays all the information, field by field how I want it...however one of the fields has a lot of text. It stops after the specified lenght with ... suggesting there is more text that doesn't fit. I have used "-2" to make it longer, but then it's too long. Also scrolling wouldn't be very nice.

I'd like it to display the information from the field on two lines, but I can't figure it out. Here's my existing text (without the dims as I've made it flat at the moment)

objConnection = CreateObject("ADODB.Connection")
		objRecordset = CreateObject("ADODB.Recordset")
		dbasename = "D:\technicianmanagement.MDB"
		tblname = "FaultCalls"
		objConnection.Open("Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " & dbasename)
		objRecordset.Open("SELECT * FROM " & tblname & " ORDER BY DATEREP DESC, TIMEREP DESC", objConnection, adOpenStatic, _
		   adLockOptimistic)

		lvref.Clear()
		lvref.View = View.Details
		lvref.Columns.Add("Ref", 40, HorizontalAlignment.Left)
		lvref.Columns.Add("User", 75, HorizontalAlignment.Left)
		lvref.Columns.Add("Asset", 100, HorizontalAlignment.Left)
		lvref.Columns.Add("Fault", -2, HorizontalAlignment.Left)
		lvref.Columns.Add("Assigned", 75, HorizontalAlignment.Left)
		lvref.Columns.Add("Date", 50, HorizontalAlignment.Left)
		lvref.Columns.Add("Time", 75, HorizontalAlignment.Left)
		lvref.Columns.Add("Email", 40, HorizontalAlignment.Left)

Do While Not objRecordset.EOF

MyListText(0) = sID
			MyListText(1) = sUser
			MyListText(2) = sAsset
			MyListText(3) = sFault
			MyListText(4) = sAssigned
			MyListText(5) = sDate
			MyListText(6) = sTime
			If sEmail = True Then MyListText(7) = "Yes" Else MyListText(7) = "No"
			MyListItem = New ListViewItem(MyListText)
			lvref.Items.Add(MyListItem)
			objRecordset.MoveNext()
Loop



#2 James Rose

    Software Developer

  • 1,918 posts
  • Joined: 20-January 04
  • Location: New York City

Posted 23 February 2012 - 19:41

The problem is that the included listview control does not support multiple lines. (sorry) The general view is that the user will expand the column so that they can see the entire text.

I did a quick search and there are comments about 3rd party controls that allow multi line, but this is an unstandard pattern so be aware.

Sorry I can't give you the answer you wanted. I would really rethink the amount of data that you are showing.

#3 FuhrerDarqueSyde

    Squirrelies!

  • 745 posts
  • Joined: 26-December 02
  • Location: Oshkosh, WI, USA
  • OS: Windows 7 Enterprise (Work)/Ultimate (Home)

Posted 23 February 2012 - 21:19

View PostDaedroth, on 23 February 2012 - 14:24, said:

Hey people!

I have pulled information from an access table into a listview item within Visual Basic 2010. It displays all the information, field by field how I want it...however one of the fields has a lot of text. It stops after the specified lenght with ... suggesting there is more text that doesn't fit. I have used "-2" to make it longer, but then it's too long. Also scrolling wouldn't be very nice.

I'd like it to display the information from the field on two lines, but I can't figure it out. Here's my existing text (without the dims as I've made it flat at the moment)

objConnection = CreateObject("ADODB.Connection")
		objRecordset = CreateObject("ADODB.Recordset")
		dbasename = "D:\technicianmanagement.MDB"
		tblname = "FaultCalls"
		objConnection.Open("Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " & dbasename)
		objRecordset.Open("SELECT * FROM " & tblname & " ORDER BY DATEREP DESC, TIMEREP DESC", objConnection, adOpenStatic, _
		   adLockOptimistic)

		lvref.Clear()
		lvref.View = View.Details
		lvref.Columns.Add("Ref", 40, HorizontalAlignment.Left)
		lvref.Columns.Add("User", 75, HorizontalAlignment.Left)
		lvref.Columns.Add("Asset", 100, HorizontalAlignment.Left)
		lvref.Columns.Add("Fault", -2, HorizontalAlignment.Left)
		lvref.Columns.Add("Assigned", 75, HorizontalAlignment.Left)
		lvref.Columns.Add("Date", 50, HorizontalAlignment.Left)
		lvref.Columns.Add("Time", 75, HorizontalAlignment.Left)
		lvref.Columns.Add("Email", 40, HorizontalAlignment.Left)

Do While Not objRecordset.EOF

MyListText(0) = sID
			MyListText(1) = sUser
			MyListText(2) = sAsset
			MyListText(3) = sFault
			MyListText(4) = sAssigned
			MyListText(5) = sDate
			MyListText(6) = sTime
			If sEmail = True Then MyListText(7) = "Yes" Else MyListText(7) = "No"
			MyListItem = New ListViewItem(MyListText)
			lvref.Items.Add(MyListItem)
			objRecordset.MoveNext()
Loop

Not sure why you dont use DataGridView.

you can do DataGridView.Columns.Add("Ref") DataGridView.Columns.Add("User") DataGridView.Columns.Add("Asset") etc.

and then for the items you can do DataGridView.Rows.Add(sID, sUser, sAsset, ...)

p.s. my VB.NET skills are rusty as I've been doing C# for a while now so ignore semicolons where not required ;p

#4 FuhrerDarqueSyde

    Squirrelies!

  • 745 posts
  • Joined: 26-December 02
  • Location: Oshkosh, WI, USA
  • OS: Windows 7 Enterprise (Work)/Ultimate (Home)

Posted 24 February 2012 - 05:15

		objConnection = CreateObject("ADODB.Connection")
		objRecordset = CreateObject("ADODB.Recordset")
		dbasename = "D:\technicianmanagement.MDB"
		tblname = "FaultCalls"
		objConnection.Open("Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " & dbasename)
		objRecordset.Open("SELECT * FROM " & tblname & " ORDER BY DATEREP DESC, TIMEREP DESC", objConnection, adOpenStatic, adLockOptimistic)

		DataGridView1.Columns.Clear()
		DataGridView1.Columns.Add("Ref", "Ref")
		DataGridView1.Columns.Add("User", "User")
		DataGridView1.Columns.Add("Asset", "Asset")
		DataGridView1.Columns.Add("Fault", "Fault")
		DataGridView1.Columns.Add("Assigned", "Assigned")
		DataGridView1.Columns.Add("Date", "Date")
		DataGridView1.Columns.Add("Time", "Time")
		DataGridView1.Columns.Add("Email", "Email")

		' Makes the form stretch to show all the columns that are visible.
		Me.Width = DataGridView1.Columns.GetColumnsWidth(DataGridViewElementStates.Visible) + 60

		' Clear all current rows of data.
		DataGridView1.Rows.Clear()

		Do While Not objRecordset.EOF
			' You would probably want to do something like this... I put an in-line if statement to shrink the amount of code needed.
			' The first parameter if If() is the expression, second is what to do if it is true and the third is what to do if it is false.
			DataGridView1.Rows.Add(sID, sUser, sAsset, sFault, sAssigned, sDate, sTime, If(sEmail, "Yes", "No"))
		Loop

That should help you along.

Or... for more column size control etc.

		objConnection = CreateObject("ADODB.Connection")
		objRecordset = CreateObject("ADODB.Recordset")
		dbasename = "D:\technicianmanagement.MDB"
		tblname = "FaultCalls"
		objConnection.Open("Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " & dbasename)
		objRecordset.Open("SELECT * FROM " & tblname & " ORDER BY DATEREP DESC, TIMEREP DESC", objConnection, adOpenStatic, adLockOptimistic)

		DataGridView1.Columns.Clear()

		Dim DGVC(7) As DataGridViewTextBoxColumn
		DGVC(0) = New DataGridViewTextBoxColumn
		DGVC(0).HeaderText = "Ref"
		DGVC(0).Name = "Ref"
		DGVC(0).Width = 40
		DGVC(1) = New DataGridViewTextBoxColumn
		DGVC(1).HeaderText = "User"
		DGVC(1).Name = "User"
		DGVC(1).Width = 75
		DGVC(2) = New DataGridViewTextBoxColumn
		DGVC(2).HeaderText = "Asset"
		DGVC(2).Name = "Asset"
		DGVC(2).Width = 100
		DGVC(3) = New DataGridViewTextBoxColumn
		DGVC(3).HeaderText = "Fault"
		DGVC(3).Name = "Fault"
		DGVC(3).Width = 140
		DGVC(4) = New DataGridViewTextBoxColumn
		DGVC(4).HeaderText = "Assigned"
		DGVC(4).Name = "Assigned"
		DGVC(4).Width = 75
		DGVC(5) = New DataGridViewTextBoxColumn
		DGVC(5).HeaderText = "Date"
		DGVC(5).Name = "Date"
		DGVC(5).Width = 50
		DGVC(6) = New DataGridViewTextBoxColumn
		DGVC(6).HeaderText = "Time"
		DGVC(6).Name = "Time"
		DGVC(6).Width = 75
		DGVC(7) = New DataGridViewTextBoxColumn
		DGVC(7).HeaderText = "Email"
		DGVC(7).Name = "Email"
		DGVC(7).Width = 40
		DataGridView1.Columns.AddRange(DGVC)

		' Makes the form stretch to show all the columns that are visible.
		Me.Width = DataGridView1.Columns.GetColumnsWidth(DataGridViewElementStates.Visible) + 60

		' Clear all current rows of data.
		DataGridView1.Rows.Clear()

		Do While Not objRecordset.EOF
			' You would probably want to do something like this... I put an in-line if statement to shrink the amount of code needed.
			' The first parameter if If() is the expression, second is what to do if it is true and the third is what to do if it is false.
			DataGridView1.Rows.Add(sID, sUser, sAsset, sFault, sAssigned, sDate, sTime, If(sEmail, "Yes", "No"))
		Loop
Attached Image: exampleprojectDGV1.png

Edited by FuhrerDarqueSyde, 24 February 2012 - 05:43.


#5 OP +Daedroth

    Resident Fanatic

  • 941 posts
  • Joined: 15-June 11
  • Location: UK

Posted 24 February 2012 - 08:28

I decided against a DataGraidView for asthetics.

I found this command:

lvref.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)

This resizes the field how I want, but again its too long. :(

Also, thanks for the help. I have added a datagridview for testing and comparison. Is there either way to make the datagridview or listview grow/shrink but keep ratios and autosize if the user resizes the form?

So if I resize the form, the text will go onto new lines, rather than the user having to use the scroll bar to view obscured text.

#6 Kami-

    ♫ d(-_-)b ♫

  • 3,624 posts
  • Joined: 28-July 08
  • Location: SandBox

Posted 24 February 2012 - 12:17

Auto-Resizing: Me.DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
Wrapping: Me.DataGridView1.RowsDefaultCellStyle.WrapMode = DataGridViewTriState.True

Useful?

(Also, you say you've gone against the DGV for Aesthetics... you can style them to look identical to a list view if you so wished... but imo you can make them look an awful lot better too!)

#7 OP +Daedroth

    Resident Fanatic

  • 941 posts
  • Joined: 15-June 11
  • Location: UK

Posted 24 February 2012 - 13:23

That's worked on some, but not all cells.

Is there any way to get it working for the rows too?

I have tried:

Me.dgvfaults.AutoResizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells

But that didn't work, as it says "'AutoResizeRowsMode' is not a member of 'System.Windows.Forms.DataGridView'"

Attached is what it looks like at the moment, but I'd like it so that it will resize with the form. Meaning it'll add extra lines if needed and shove the teext down.

Attached Images

  • Attached Image: Untitled.png


#8 +Bamsebjorn

    Neowinian Teddy Bear

  • 1,191 posts
  • Joined: 23-May 05
  • Location: Dordrecht, The Netherlands

Posted 24 February 2012 - 13:39

Try overriding the ondrawlistitem event... not sure how to do it in VB.NET, if you want I'll try to write a sample...

#9 monkey13

    Resident Elite

  • 1,481 posts
  • Joined: 05-October 03

Posted 24 February 2012 - 13:39

After the loop can't you just do.

lvref.Columns(3).Width = -1

That should resize it to the largest data item in the column. You may be able to set it to -1 before the loop and then it will do it as the data is added. My VB is very rusty so I can't remember exactly how it works (so rusty I could be way off as well)

#10 +Bamsebjorn

    Neowinian Teddy Bear

  • 1,191 posts
  • Joined: 23-May 05
  • Location: Dordrecht, The Netherlands

Posted 24 February 2012 - 14:06

I've just programmed my first VB.NET in 2 years... here's a simple implementation of a ListBox with custom drawn mutli line items. Use it as you like...

(something went wrong, the attachment is attached twice)

Attached Files