Advanced User Interface Controls and Components
May 06, 2011
By default when adding objects in ListBox they are only displayed in simple list. However, in some cases we want to show more details in single item related to the same object. And we want to show not only just text, but also images in different sizes, hyperlinks, buttons etc.
We will show you how to do that using IntegralUI ListBox .NET control. This control has an option to create templates using HTML tags and arrange various objects like text, images, hyperlinks, custom controls etc. in custom layouts in single item. Many of already known HTML tags are supported which helps in creation of different layouts.
Let's start by creation of our custom object. For example let's create a Product class which will contain information about product: ID, Name, Category, Price and Rating.
public class Product : System.Object
{
private int _id = -1;
private String _name = String.Empty;
private String _category = String.Empty;
private String _imageSource = String.Empty;
private double _price = 0.0f;
private int _rating = 0;
public Product(int id)
{
Init(id, String.Empty, String.Empty, 0, 0);
}
public Product(int id, String name, String category)
{
Init(id, name, category, 0, 0);
}
private void Init(int id, String name, String category, double price, int rating)
{
int _id = id;
String _name = name;
String _category = category;
double _price = price;
int _rating = rating;
}
public int ID
{
get { return _id; }
}
public String Name
{
get { return _name; }
set { _name = value; }
}
public String Category
{
get { return _category; }
set { _category = value; }
}
public String ImageSource
{
get { return _imageSource; }
set { _imageSource = value; }
}
public double Price
{
get { return _price; }
set { _price = value; }
}
public int Rating
{
get { return _rating; }
set { _rating = value; }
}
}
Public Class Product Inherits System.Object
Private _id As Integer = -1
Private _name As String = String.Empty
Private _category As String = String.Empty
Private _imageSource As String = String.Empty
Private _price As Double = 0.0F
Private _rating As Integer = 0
Public Sub New(ByVal id As Integer)
Init(id, String.Empty, String.Empty, 0, 0)
End Sub
Public Sub New(ByVal id As Integer, ByVal name As String, ByVal category As String)
Init(id, name, category, 0, 0)
End Sub
Private Sub Init(ByVal id As Integer, ByVal name As String, ByVal category As String, ByVal price As Double, ByVal rating As Integer)
Dim _id As Integer = id
Dim _name As String = name
Dim _category As String = category
Dim _price As Double = price
Dim _rating As Integer = rating
End Sub
Public ReadOnly Property ID() As Integer
Get
Return _id
End Get
End Property
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Property Category() As String
Get
Return _category
End Get
Set(ByVal value As String)
_category = value
End Set
End Property
Public Property ImageSource() As String
Get
Return _imageSource
End Get
Set(ByVal value As String)
_imageSource = value
End Set
End Property
Public Property Price() As Double
Get
Return _price
End Get
Set(ByVal value As Double)
_price = value
End Set
End Property
Public Property Rating() As Integer
Get
Return _rating
End Get
Set(ByVal value As Integer)
_rating = value
End Set
End Property
End Class
Now we need to construct a template which will be used to arrange details for each product. For this purpose we will use <table> tag because it gives a uniform layout. The template should allow us to show product image to far left, product name on top following with detail information in middle. Additionally we want to show a button or hyperlink which when clicked will open for example a window with more details about the product. Here is the template sample:
private String ApplyTemplate(Product obj)
{
String content = String.Empty;
content = "<div>";
content += "<table cellpadding=\"2\" width=\"100%\">";
content += "<tr>";
content += "<td rowspan=\"2\"><img assemblypath=\"" + assemblyFullPath + "\" resource=\"Resources." + obj.ImageSource + "\"></img></td>";
content += "<td width=\"100%\"><font size=\"10\">" + obj.Name + "</font></td>";
content += "<td style=\"align:middleright;textcolor:DarkBlue\">" + obj.Category + "</td>";
content += "<td style=\"align:middlecenter;hovertextcolor:DarkRed\" width=\"50\"><a href=\"" + obj.Name + "\">more ...</a></td>";
content += "</tr>";
content += "<tr>";
content += "<td>><control index=\"0\"></control></td>";
content += "<td style=\"align:middleright\"><b>" + obj.Price.ToString("0.00") + "</b></td>";
content += "</tr>";
content += "</table>";
content += "</div>";
return content;
}
Private Function ApplyTemplate(ByVal obj As Product) As String
Dim content As String = String.Empty
content = "<div>";
content += "<table cellpadding=""2"" width=""100%"">";
content += "<tr>";
content += "<td rowspan=""2""><img assemblypath=""" & assemblyFullPath & """ resource=""Resources." & obj.ImageSource & """></img></td>";
content += "<td width=""100%""><font size=""10"">" & obj.Name & "</font></td>";
content += "<td style=""align:middleright;textcolor:DarkBlue"">" & obj.Category & "</td>";
content += "<td style=""align:middlecenter;hovertextcolor:DarkRed"" width=""50""><a href=""" & obj.Name & """>more ...</a></td>";
content += "</tr>";
content += "<tr>";
content += "<td>><control index=""0""></control></td>";
content += "<td style=""align:middleright""><b>" & obj.Price.ToString("0.00") & "</b></td>";
content += "</tr>";
content += "</table>";
content += "</div>";
Return content;
End Function
We will use the same template to display all products. But if you want, you can apply different template for each item.
Now let's create a list of 10 products:
private void InitList()
{
this.listBox1.SuspendUpdate();
this.listBox1.NormalItemStyle.BorderColor = Color.LightGray;
Product obj = null;
LidorSystems.IntegralUI.Lists.ListBoxItem item = null;
for (int i = 0; i < 10; i++)
{
item = new LidorSystems.IntegralUI.Lists.ListBoxItem();
obj = CreateProduct(i);
item.Content = ApplyTemplate(obj);
item.Tag = obj;
ProgressBar ctrlRate = new ProgressBar();
ctrlRate.Size = new Size(70, 12);
ctrlRate.Minimum = 0;
ctrlRate.Maximum = 5;
ctrlRate.Value = obj.Rating;
item.Controls.Add(ctrlRate);
this.listBox1.Items.Add(item);
}
this.listBox1.ResumeUpdate();
}
private Product CreateProduct(int index)
{
Product obj = new Product(index);
switch (index % 3)
{
case 1:
obj.Name = "Thüringer Rostbratwurst";
obj.Category = "Meat";
obj.Rating = 2;
obj.Price = 123.79f;
obj.ImageSource = "meat.jpg";
break;
case 2:
obj.Name = "Scottish Longbreads";
obj.Category = "Confections";
obj.Rating = 4;
obj.Price = 12.50f;
obj.ImageSource = "confections.jpg";
break;
default:
obj.Name = "Ipoh Coffee";
obj.Category = "Beverages";
obj.Rating = 3;
obj.Price = 46.00f;
obj.ImageSource = "beverages.jpg";
break;
}
return obj;
}
Private Sub InitList()
Me.listBox1.SuspendUpdate()
Dim obj As Product = Nothing
Dim item As LidorSystems.IntegralUI.Lists.ListBoxItem = Nothing
For i As Integer = 0 To 9
item = New LidorSystems.IntegralUI.Lists.ListBoxItem()
obj = CreateProduct(i)
item.Content = ApplyTemplate(obj)
item.Tag = obj
Dim ctrlRate As New ProgressBar()
ctrlRate.Size = New Size(70, 12)
ctrlRate.Minimum = 0
ctrlRate.Maximum = 5
ctrlRate.Value = obj.Rating
item.Controls.Add(ctrlRate)
Me.listBox1.Items.Add(item)
Next
Me.listBox1.ResumeUpdate()
End Sub
Private Function CreateProduct(ByVal index As Integer) As Product
Dim obj As New Product(index)
Select Case index Mod 3
Case 1
obj.Name = "Thüringer Rostbratwurst"
obj.Category = "Meat"
obj.Rating = 2
obj.Price = 123.79F
obj.ImageSource = "meat.jpg"
Exit Select
Case 2
obj.Name = "Scottish Longbreads"
obj.Category = "Confections"
obj.Rating = 4
obj.Price = 12.5F
obj.ImageSource = "confections.jpg"
Exit Select
Case Else
obj.Name = "Ipoh Coffee"
obj.Category = "Beverages"
obj.Rating = 3
obj.Price = 46.0F
obj.ImageSource = "beverages.jpg"
Exit SelectEnd Select
Return obj
End Function
For this demo we are creating the product list from three types of products. We little modification this could easily be adjusted with data from some database or any other dataset. As a result, all products are shown with more details. You can notice that we are using text, images, hyperlinks and ProgressBar control to show various data for each product.
A complete sample project in C# and VB showing how to create a listbox where each item display various objects in custom layout using a template is available for download from here: ListBox .NET Rich Content Sample