获取或设置选择用于显示每个项的模板的自定义逻辑。这是一个依赖项属性。DataTemplateSelector 这个属性是 ItemsControl 下的一个依赖属性 VS对他是这么描述的
"获取或设置选择用于显示每个项的模板的自定义逻辑。这是一个依赖项属性。"
很明显,它就是可以根据绑定源来决定呈现在控件上面的东西,相当于可以同时绑定多个ItemDataTemplate。
先定义好资源 多个DataTemplate
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate x:Key="ListBoxItemImage">
<Grid Height="100" Width="250">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageURL}" Stretch="Uniform" Width="50" Height="50"></Image>
<TextBlock Text="{Binding Text}" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextWrapping="WrapWithOverflow" TextTrimming="WordEllipsis"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="ListboxItemTextBlock">
<Grid Height="100" Width="250">
<TextBlock Text="{Binding Text}" VerticalAlignment="Top" HorizontalAlignment="Left" TextWrapping="WrapWithOverflow" TextTrimming="WordEllipsis"/>
</Grid>
</DataTemplate>
</ResourceDictionary>
一个是专门显示图片的,一个是专门负责显示文字描述的template,这时候会有个问题:“依赖属性
DataTemplateSelector只有一个啊,我在XAML里面
怎么把这两个东西赋值进去?”
所以,我们现在得创造自己的DatatTemplate 得把原来的继承过来改造一下。
新建一个class 继承DatatTemplate 如下:
我们重写了SelectTemplate 这个方法,当绑定源时候就会触发此事件,item 当然是 实体类了。
我们通过强大的反射工具来获取已经定义好的 要显示文字还是图片的属性,获取这个值后再决定返回
哪一个template。
public class Testdatatemplate : DataTemplateSelector
{
public DataTemplate Imagetemplate
{ get; set; }
public DataTemplate Texttemplate
{ get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
Type t = item.GetType();
PropertyInfo p = t.GetProperty("ShowType");
if (p == null)
return base.SelectTemplate(item, container);
string showtype = p.GetValue(item, null) as string;
if (string.IsNullOrEmpty(showtype))
return base.SelectTemplate(item, container);
switch (showtype)
{
case "Image":
return Imagetemplate;
case "Text":
return Texttemplate;
default:
return null;
}
}
}
这样就可以赋值多个template了。
然后我们进入xaml 把listbox 的 ItemsDataTemplateSelector 赋值:
<ListBox Name="lstbox" Margin="56,42,123,60" ItemsPanel="{DynamicResource ItemsPanelTemplate2}">
<ListBox.ItemTemplateSelector>
<local:Testdatatemplate Imagetemplate="{StaticResource ListboxItemTextBlock}"
Texttemplate="{StaticResource ListBoxItemImage}">
</local:Testdatatemplate>
</ListBox.ItemTemplateSelector>
</ListBox>
噢,差点忘记了, binding源 别忘记了。 我创建了一个实体类,Text 当然是要显示的文字,ImageUrl 就是图片的路径 showType 就是自己决定显示图片还是文字
文字的属性了。
public class DataEntity : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public string Text { get;set;}
public string ImageURL { get; set; }
public string ShowType { get; set; }
}
然后我们在后天创建一个list 赋值给listbox
public partial class GridViewWin : Window
{
public GridViewWin()
{
this.InitializeComponent();
// 在此点之下插入创建对象所需的代码。
ObservableCollection<DataEntity> list = new ObservableCollection<DataEntity>()
{
new DataEntity(){Text = "Nike Air Force 1出生于1982年,深深地根"+
"植于篮球运动之中。当时挑选了6位篮球运动员来代言这款鞋。"+
"经典的海报,强硬的姿态,马龙和他的伙伴们展示出AF1成功"+
"的六大要素:宏大、耐久、超越、豪迈、连贯和纯粹。AF1征服了地球!",ImageURL="QQ图片20140331143305.jpg",ShowType="Image"},
new DataEntity(){Text = "Nike Air Force 1出生于1982年,深深地根"+
"植于篮球运动之中。当时挑选了6位篮球运动员来代言这款鞋。"+
"经典的海报,强硬的姿态,马龙和他的伙伴们展示出AF1成功"+
"的六大要素:宏大、耐久、超越、豪迈、连贯和纯粹。AF1征服了地球!",ImageURL="QQ图片20140331143305.jpg",ShowType="Image"},
new DataEntity(){Text = "Nike Air Force 1出生于1982年,深深地根"+
"植于篮球运动之中。当时挑选了6位篮球运动员来代言这款鞋。"+
"经典的海报,强硬的姿态,马龙和他的伙伴们展示出AF1成功"+
"的六大要素:宏大、耐久、超越、豪迈、连贯和纯粹。AF1征服了地球!",ImageURL="QQ图片20140331143305.jpg",ShowType="Text"},
new DataEntity(){Text = "Nike Air Force 1出生于1982年,深深地根"+
"植于篮球运动之中。当时挑选了6位篮球运动员来代言这款鞋。"+
"经典的海报,强硬的姿态,马龙和他的伙伴们展示出AF1成功"+
"的六大要素:宏大、耐久、超越、豪迈、连贯和纯粹。AF1征服了地球!",ImageURL="QQ图片20140331143305.jpg",ShowType="Text"},
};
lstbox.ItemsSource = list;
}
}
运行效果: