The ListControl looks exactly like the old ListBox, but it has better performance and fully supports virtualization.
I have prepared a small proof of concept that creates a label and two images for a list Item,
namespace
RadListControlCustomItems
{
using
System;
using
System.ComponentModel;
using
System.Drawing;
using
System.Windows.Forms;
using
Telerik.WinControls;
using
Telerik.WinControls.Enumerations;
using
Telerik.WinControls.Layouts;
using
Telerik.WinControls.Primitives;
using
Telerik.WinControls.UI;
public
partial
class
Form1 : Form
{
private
RadListControl radListControl1;
public
Form1()
{
InitializeComponent();
this
.radListControl1 =
new
RadListControl();
this
.Size =
new
Size(500, 300);
this
.Load +=
new
System.EventHandler(Form1_Load);
}
void
Form1_Load(
object
sender, System.EventArgs e)
{
radListControl1.Dock = DockStyle.Fill;
this
.radListControl1.CreatingVisualListItem += CreatingVisualListItem;
this
.radListControl1.ItemDataBinding +=
this
.ItemDataBinding;
this
.radListControl1.ItemDataBound +=
this
.ItemDataBound;
this
.Controls.Add(radListControl1);
PrepareDataSourceAndShowDropDown(1000);
}
private
void
PrepareDataSourceAndShowDropDown(
int
noObjects)
{
this
.radListControl1.DataSource =
null
;
this
.radListControl1.DisplayMember =
"Name"
;
BindingList<BussinessObject> list =
new
BindingList<BussinessObject>();
for
(
int
i = 0; i < noObjects; ++i)
{
BussinessObject businessObject =
new
BussinessObject();
businessObject.Image = Properties.Resources.combobox;
businessObject.Image2 = i % 2 == 0 ? Properties.Resources.calendar :
null
;
businessObject.Name =
" Item "
+ (i + 1);
list.Add(businessObject);
}
this
.radListControl1.DataSource = list;
}
#region Event Handlers
private
void
ItemDataBound(
object
sender, ListItemDataBoundEventArgs args)
{
CustomListDataItem listDataItem = (CustomListDataItem)args.NewItem;
BussinessObject dataObject = (BussinessObject)listDataItem.DataBoundItem;
listDataItem.Name = dataObject.Name;
listDataItem.Image = dataObject.Image;
listDataItem.Image2 = dataObject.Image2;
}
private
void
ItemDataBinding(
object
sender, ListItemDataBindingEventArgs args)
{
args.NewItem =
new
CustomListDataItem();
}
private
void
CreatingVisualListItem(
object
sender, CreatingVisualListItemEventArgs args)
{
args.VisualItem =
new
CustomListVisualItem();
}
#endregion Event Handlers
#region Overrides
#endregion Overrides
}
public
class
BussinessObject : INotifyPropertyChanged
{
#region Fields
private
string
name;
private
Image image;
private
Image image2;
#endregion Fields
#region Properties
public
string
Name
{
get
{
return
name;
}
set
{
if
(
this
.name == value)
{
return
;
}
this
.name = value;
this
.OnNotifyPropertyChanged(
"Name"
);
}
}
public
Image Image
{
get
{
return
this
.image;
}
set
{
if
(
this
.image == value)
{
return
;
}
this
.image = value;
this
.OnNotifyPropertyChanged(
"Image"
);
}
}
public
Image Image2
{
get
{
return
this
.image2;
}
set
{
if
(
this
.image2 == value)
{
return
;
}
this
.image2 = value;
this
.OnNotifyPropertyChanged(
"Image2"
);
}
}
#endregion Properties
#region INotifyPropertyChanged Implementation
public
event
PropertyChangedEventHandler PropertyChanged;
private
void
OnNotifyPropertyChanged(
string
property)
{
if
(
this
.PropertyChanged !=
null
)
{
this
.PropertyChanged(
this
,
new
PropertyChangedEventArgs(property));
}
}
#endregion INotifyPropertyChanged Implementation
}
public
class
CustomListDataItem : RadListDataItem
{
#region RadProperties
public
static
readonly
RadProperty ImageProperty = RadProperty.Register(
"Image"
,
typeof
(Image),
typeof
(CustomListDataItem),
new
RadElementPropertyMetadata(
null
));
public
static
readonly
RadProperty Image2Property = RadProperty.Register(
"Image2"
,
typeof
(Image),
typeof
(CustomListDataItem),
new
RadElementPropertyMetadata(
null
));
public
static
readonly
RadProperty NameProperty = RadProperty.Register(
"Name"
,
typeof
(
string
),
typeof
(CustomListDataItem),
new
RadElementPropertyMetadata(
""
));
#endregion RadProperties
#region Properties
public
new
Image Image
{
get
{
return
(Image)
this
.GetValue(CustomListDataItem.ImageProperty);
}
set
{
this
.SetValue(CustomListDataItem.ImageProperty, value);
}
}
public
Image Image2
{
get
{
return
(Image)
this
.GetValue(CustomListDataItem.Image2Property);
}
set
{
this
.SetValue(CustomListDataItem.Image2Property, value);
}
}
public
string
Name
{
get
{
return
(
string
)
this
.GetValue(CustomListDataItem.NameProperty);
}
set
{
this
.SetValue(CustomListDataItem.NameProperty, value);
}
}
#endregion Properties
#region Overrides
protected
override
void
SetDataBoundItem(
bool
dataBinding,
object
value)
{
base
.SetDataBoundItem(dataBinding, value);
if
(value
is
INotifyPropertyChanged)
{
INotifyPropertyChanged item = value
as
INotifyPropertyChanged;
item.PropertyChanged += item_PropertyChanged;
}
}
#endregion Overrides
#region Private Methods
private
void
item_PropertyChanged(
object
sender, PropertyChangedEventArgs e)
{
if
(e.PropertyName ==
"Image"
)
{
this
.Image = (
this
.DataBoundItem
as
BussinessObject).Image;
}
if
(e.PropertyName ==
"Image2"
)
{
this
.Image2 = (
this
.DataBoundItem
as
BussinessObject).Image2;
}
if
(e.PropertyName ==
"Name"
)
{
this
.Name = (
this
.DataBoundItem
as
BussinessObject).Name;
}
}
#endregion Private Methods
}
public
class
CustomListVisualItem : RadListVisualItem
{
#region Fields
private
RadLabelElement label =
new
RadLabelElement();
private
ImagePrimitive image =
new
ImagePrimitive();
private
ImagePrimitive image2 =
new
ImagePrimitive();
#endregion Fields
#region Initialization
static
CustomListVisualItem()
{
RadListVisualItem.SynchronizationProperties.Add(CustomListDataItem.ImageProperty);
RadListVisualItem.SynchronizationProperties.Add(CustomListDataItem.Image2Property);
RadListVisualItem.SynchronizationProperties.Add(CustomListDataItem.NameProperty);
}
#endregion Initialization
#region Overrides
protected
override
Type ThemeEffectiveType
{
get
{
return
typeof
(RadListVisualItem);
}
}
protected
override
void
CreateChildElements()
{
base
.CreateChildElements();
this
.label.StretchHorizontally =
true
;
var stack =
new
StackLayoutPanel { Orientation = Orientation.Horizontal };
image.ImageScaling = ImageScaling.SizeToFit;
image2.ImageScaling = ImageScaling.SizeToFit;
stack.Children.Add(label);
stack.Children.Add(image);
stack.Children.Add(image2);
this
.Children.Add(stack);
}
protected
override
void
PropertySynchronized(RadProperty property)
{
var dataItem = (CustomListDataItem)
this
.Data;
this
.image2.Image = dataItem.Image2;
this
.image.Image = dataItem.Image;
this
.label.Text = dataItem.Name;
}
#endregion Overrides
}
}
Hope this helps, if you have any other questions or comments, please let me know,