Silverlight-TabControl扩展(2)

上一篇简单扩展了TabControl的ItemsSource属性。只是只能应用一个统一的模板展示数据,但是毕竟ItemsSource是IEnumerable类型的,这就意味着里面的每个Item都可以有自己不同的Type,而相同的DataTemolate可能并不适用。

在WPF和SL5中可以给DataTemplate标记DataType,这样ItemsControl会去自己识别相应的类型所需的模板。在SL4中也让我们来简单实践下。

在TabControlExtensions类里增加一个DataTemplate的附加属性,实验证明Type类型并不能很好的被编译器识别,还是用string了。

View Code
private static Dictionary < string , DataTemplate > _templateStore = new Dictionary < string , DataTemplate > ();

public static string GetDataTypeName(DependencyObject d)
{
return ( string )d.GetValue(DataTypeNameProperty);
}

public static void SetDataTypeName(DependencyObject d, string value)
{
d.SetValue(DataTypeNameProperty, value);
}

public static readonly DependencyProperty DataTypeNameProperty =
DependencyProperty.Register(
" DataTypeName " , typeof ( string ), typeof (DataTemplate),
new PropertyMetadata(OnDataTypeNameChanged));


private static void OnDataTypeNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var template
= d as DataTemplate;
var typeName
= ( string )e.NewValue;
if ( ! string .IsNullOrEmpty(typeName))
{
_templateStore[typeName]
= template;
}
}

在回调方法里把相应的键值存储到一个静态字典里,以便以后取用。

稍微改一下上次的那个Animal类,继承增加三个不同的类型。

View Code
public abstract class Animal
{
public abstract string Name { get ; }
public int Count { get ; set ; }
public string From { get ; set ; }
}

public class Zabra : Animal
{
public override string Name
{
get { return " 斑马 " ; }
}
}

public class Penguin : Animal
{
public override string Name
{
get { return " 企鹅 " ; }
}
}

public class Lemur : Animal
{

public override string Name
{
get { return " 环尾狐猴 " ; }
}
}

然后就是在Resources里为三个不同的类型增加三个不同的DataTemplate。

View Code
< UserControl.Resources >
< DataTemplate x:Key ="s" local:TabControlExtensions.DataTypeName ="Penguin" >
< Grid Background ="Black" >
< Grid.RowDefinitions >
< RowDefinition Height ="0.2*" />
< RowDefinition Height ="0.6*" />
< RowDefinition Height ="0.2*" />
</ Grid.RowDefinitions >
< Grid.ColumnDefinitions >
< ColumnDefinition Width ="0.2*" />
< ColumnDefinition Width ="0.6*" />
< ColumnDefinition Width ="0.2*" />
</ Grid.ColumnDefinitions >
< Rectangle Grid.Column ="1" Fill ="White" Grid.Row ="1" />
</ Grid >
</ DataTemplate >

< DataTemplate x:Key ="ss" local:TabControlExtensions.DataTypeName ="Zabra" >
< Grid >
< Grid.Background >
< LinearGradientBrush EndPoint ="20,20" SpreadMethod ="Repeat" MappingMode ="Absolute" >
< GradientStop Color ="Black" Offset ="0" />
< GradientStop Color ="Black" Offset ="0.5" />
< GradientStop Color ="White" Offset ="0.5" />
< GradientStop Color ="White" Offset ="1" />
</ LinearGradientBrush >
</ Grid.Background >
</ Grid >
</ DataTemplate >

< DataTemplate x:Key ="sss" local:TabControlExtensions.DataTypeName ="Lemur" >
< Grid >
< Grid.ColumnDefinitions >
< ColumnDefinition Width ="0.5*" />
< ColumnDefinition Width ="0.5*" />
</ Grid.ColumnDefinitions >
< Rectangle Grid.Column ="1" >
< Rectangle.Fill >
< LinearGradientBrush EndPoint ="0,0" StartPoint ="30,0" SpreadMethod ="Repeat" MappingMode ="Absolute" >
< GradientStop Color ="Black" Offset ="0" />
< GradientStop Color ="Black" Offset ="0.5" />
< GradientStop Color ="White" Offset ="0.5" />
< GradientStop Color ="White" Offset ="1" />
</ LinearGradientBrush >
</ Rectangle.Fill >
</ Rectangle >
</ Grid >
</ DataTemplate >
</ UserControl.Resources >

x:key随便写一下,并为每个DataTemplate设置local:TabControlExtensions.DataTypeName附加属性,属性的值为对应的需要呈现此模板的类名,可见第一个模板是给企鹅的,第二个是给斑马的,第三个是给狐猴的。

最后只要对上次的那个OnItemsSourceChanged方法稍作调整就行了。

View Code
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var source
= d as TabControl;
var items
= e.NewValue as IEnumerable;

source.Items.Clear();

if (items != null )
{
var headerTemplate
= GetHeaderTemplate(source);
var contentTemplate
= GetContentTempalte(source);

foreach (var item in items)
{
// -------
var typeName = item.GetType().Name;
var itemTemplate
= _templateStore.ContainsKey(typeName) ? _templateStore[typeName] : null ;
// -------

var tabItem
= new TabItem
{
DataContext
= item,
Header
= item,
HeaderTemplate
= headerTemplate,
Content
= item,
// ---------
ContentTemplate = itemTemplate ?? contentTemplate,
// ---------
};
source.Items.Add(tabItem);
}
}
}

增加的部分代码用注释标记了,从存储了键值的字典里根据Type的Name获取相应的模板,很简单。

看下效果,条纹斑马:

Silverlight-TabControl扩展(2)

白肚皮黑身体的企鹅:

Silverlight-TabControl扩展(2)

一圈一圈尾巴的环尾狐猴:

Silverlight-TabControl扩展(2)

以及代码:这里

你可能感兴趣的:(silverlight)