Well, the problem here is a listbox has the ability to have a "hidden" column (usually the database PK id), and then one column for display.
Since a listbox always shows (unlike a combo/dropdown list), then it stands to reason that using a listview, or gridview is a MUCH better choice.
Not clear why someone would suggest using a control that does not support multiple columns, and then you being told to display multiple columns? (some kind of drunken rodeo clown is clearly asking you to do something that makes no more sense than demonstrating to driving a car in reverse down a busy freeway).
ok, so having stated the above? And having stated that a gridview is a FAR better choice?
Well, you need to first choose a "fixed" font size. (Since with multiple columns, there is little hope of the columns to algin up).
so, lets drop in a listview, and fill it with say hotel name, city, and if it is active or not.
So, our list view markup is this:
<asp:ListBox ID="ListBox1" runat="server"
DataValueField ="ID"
DataTextField = "MyHotel" >
</asp:ListBox>
And now our code to load up the 3 columns (hotel name, city, and "active"). And of course, the value returned for a selection (not displayed) like all typical listbox will remain the database pk row of "ID".
And we need to pad (use fixed column length).
And, a listbox will gobble up spaces (html), so we need to use "160" (a ).
so this code:
void LoadData()
{
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL =
@"SELECT ID, HotelName, City, Active FROM tblHotelsA
ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
dt.Load(cmdSQL.ExecuteReader());
dt.Columns.Add("MyHotel");
foreach (DataRow dr in dt.Rows)
{
string MyHotel =
mypad(dr["HotelName"].ToString(), 20) + " |" +
mypad(dr["City"].ToString(), 12) + " |" +
mypad(dr["Active"].ToString(), 5);
dr["MyHotel"] = MyHotel;
}
ListBox1.DataSource = dt;
ListBox1.DataBind();
}
}
}
public string mypad(string s, int padlen)
{
int iLen = padlen - s.Length;
if (iLen < 0)
iLen = 0;
string sResult = s + string.Concat(Enumerable.Repeat(Convert.ToChar(160), iLen));
return sResult;
}
And we now see/get this:

ToStringto display a string consisting of the concatenated columns. Add the objects to aList<TheClass>and use it as data source.