我为啥称之为“动态数据模板”?先看看下面的截图,今天,我们就是要实现这种功能。

 

大概是这样的,我们定义的DataTemplate是通过触发器动态应用到 ComboBoxItem 上。

这个下拉列表控件绑定了一个Person集合,Person类的定义如下:

 

[csharp] view plain copy
 
  1. public class Person  
  2. {  
  3.     public string Name { get; set; }  
  4.     public int Age { get; set; }  
  5.     public string Email { get; set; }  
  6.     public override string ToString()  
  7.     {  
  8.         return Name;  
  9.     }  
  10. }  


 

这里重写了ToString方法,因为ComboBox生成的项是调用对象的ToString方法的,为了能不设置数据模板的前提下正确显示列表项,需要重写ToString方法,默认显示姓名属性。
 
然后,我们为ComboBoxItem定义一个处于高亮状态时使用的数据模板,也就是当鼠标移到项上时发生。
[html] view plain copy
 
  1. <Window.Resources>  
  2.     <!-- 
  3.         当项高亮显示时使用的数据模板 
  4.     -->  
  5.     <DataTemplate x:Key="hightlightTmp">  
  6.         <Grid>  
  7.             <Grid.RowDefinitions>  
  8.                 <RowDefinition Height="auto"/>  
  9.                 <RowDefinition Height="auto"/>  
  10.             </Grid.RowDefinitions>  
  11.             <StackPanel Margin="0,5,0,0" Grid.Row="0" Orientation="Horizontal">  
  12.                 <TextBlock Margin="2,0" FontWeight="Bold" FontSize="14">  
  13.                             <TextBlock.Text>  
  14.                                 <Binding Path="Name"  
  15.                                          StringFormat="姓名:{0}"/>  
  16.                             </TextBlock.Text>  
  17.                 </TextBlock>  
  18.                 <TextBlock Margin="20,0">  
  19.                             <TextBlock.Text>  
  20.                                 <Binding Path="Age"  
  21.                                          StringFormat="年龄:{0}"/>  
  22.                             </TextBlock.Text>  
  23.                 </TextBlock>  
  24.             </StackPanel>  
  25.             <TextBlock Margin="0,2,0,5" Grid.Row="1">  
  26.                         <TextBlock.Text>  
  27.                             <Binding Path="Email"  
  28.                                      StringFormat="电邮:{0}"/>  
  29.                         </TextBlock.Text>  
  30.             </TextBlock>  
  31.         </Grid>  
  32.     </DataTemplate>  
  33.        ..............          
  34. </Window.Resources>  


 

为 ComboBoxItem 定义一个样式。
[html] view plain copy
 
  1. <Window.Resources>  
  2.      ................          
  3.     <!-- 项样式 -->  
  4.     <Style x:Key="cmbStyle" TargetType="{x:Type ComboBoxItem}">  
  5.         <Style.Triggers>  
  6.             <Trigger Property="IsHighlighted" Value="True">  
  7.                 <Setter Property="ContentTemplate"  
  8.                         Value="{StaticResource hightlightTmp}"/>  
  9.             </Trigger>  
  10.         </Style.Triggers>  
  11.     </Style>  
  12. </Window.Resources>  


 

在窗体中声明一个ComboBox。
[html] view plain copy
 
  1. <Grid>  
  2.     <ComboBox x:Name="cmb" Margin="10,10"  
  3.               Height="24" Width="200"  
  4.               HorizontalAlignment="Left"  
  5.               VerticalAlignment="Top"  
  6.               ItemContainerStyle="{StaticResource cmbStyle}"/>  
  7. </Grid>  


 

最后,切换到代码视图,完成设置数据源的C#代码。
[csharp] view plain copy
 
  1. public Window1()  
  2. {  
  3.     InitializeComponent();  
  4.     this.cmb.ItemsSource = new Person[]  
  5.     {  
  6.         new Person{Name="小李",Age=22,Email="suk211@163.com"},  
  7.         new Person{Name="小王",Age=20,Email="minat@126.com"},  
  8.         new Person{Name="黄涨",Age=21,Email="laned2@21cn.com"},  
  9.         new Person{Name="高产",Age=22,Email="ha@136.com"},  
  10.         new Person{Name="杜林",Age=21,Email="null@yaahoo.com"},  
  11.         new Person{Name="杨白姥",Age=50,Email="cYang@21cn.com"},  
  12.         new Person{Name="鸟人",Age=31,Email="bgl@ask.net.cn"},  
  13.         new Person{Name="宋小八",Age=28,Email="xde227@123h.com"}  
  14.     };  
  15. }  


 

完成,这时候运行一下,你会看到上文中截图中的效果了。