下面我来自定义类似系统ListBox的MyListBox控件,里面包含模版属性ItemTeamplate。
1、添加新类MyListBox.cs,让它继承自Grid:
[TemplatePart(Name = "ItemTemplate", Type = typeof(UIElement))]
public class MyListBox : Grid
2、添加ItemTemplate模版属性:
public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register(
"ItemTemplate", typeof(DataTemplate), typeof(MyListBox), null);
public DataTemplate ItemTemplate
{
get
{
return (DataTemplate)this.GetValue(MyListBox.ItemTemplateProperty);
}
set
{
this.SetValue(MyListBox.ItemTemplateProperty, value);
}
}
3、添加ItemsSource属性,在ItemsSource变化时绘制控件:
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IList), typeof(MyListBox),
new PropertyMetadata(null, OnItemsSourceChange));
/// <summary>
/// 列表内容数据源
/// </summary>
public IList ItemsSource
{
get
{
return (IList)this.GetValue(MyListBox.ItemsSourceProperty);
}
set
{
base.SetValue(MyListBox.ItemsSourceProperty, value);
}
}
private static void OnItemsSourceChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyListBox listbox = d as MyListBox;
if (null != listbox)
listbox.Draw();
}
4、实现Draw方法绘制控件:
private void Draw()
{
this.Children.Clear();
if (null == this.ItemsSource || null == this.ItemTemplate)
return;
//绘制所有Item
ScrollViewer scrollViewer = new ScrollViewer
{
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
Margin = new Thickness(0, 0, 0, 0),
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top
};
Canvas canvas = new Canvas
{
Background = new SolidColorBrush(Colors.Transparent),
Width = _nItemWidth,
Height = _nItemHeight * ItemsSource.Count
};
for (int i = 0; i < this.ItemsSource.Count; i++)
{
//绘制一个Item
ContentPresenter item = this.CreateItem(ItemsSource[i], ItemTemplate,
_nItemWidth, _nItemHeight, 0, i * _nItemHeight);
canvas.Children.Add(item);
}
scrollViewer.Content = canvas;
this.Children.Add(scrollViewer);
}
5、Draw方法里面的关键是调用CreateItem方法把ItemTemplate和当前的绑定object生成一个ContentPresenter:
private ContentPresenter CreateItem(object content, DataTemplate itemTemplate,
double width, double height, double left, double top)
{
ContentPresenter item = new ContentPresenter()
{
Content = content,
ContentTemplate = itemTemplate,
Height = height,
Width = width
};
item.SetValue(Canvas.LeftProperty, left);
item.SetValue(Canvas.TopProperty, top);
return item;
}