Silverlight之Template
其实在Silverlight中有一个部分非常重要,那就是模板,这个模板是最复杂但也是最巧妙的地方,因为有了模板就可以制定任何你想要的控件,但是这个模板也是最复杂的地方,因为其太过灵活了,下面看一个ListBox的模板设置:
<ListBox Name="lstProducts" HorizontalContentAlignment="Stretch"
SelectionChanged="lstProducts_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue"
CornerRadius="4">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock FontWeight="Bold"
Text="{Binding ModelNumber}"></TextBlock>
<TextBlock Grid.Row="1"
Text="{Binding ModelName}"></TextBlock>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
可以看到这ListBox.ItemTemplate(就是ListBox的项模板,也就是每一项的显示格式)中包含一个DataTemplate,在DataTemplate中放置了一个Grid,在Grid中放置
了两个TextBlock用来显示信息。
当然也可以把模板放置到Resource中:
<DataTemplate x:Key="listTemplate" >
<Border Margin="5" Width="200" BorderBrush="SteelBlue" BorderThickness="1" CornerRadius="5">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding ProductName}"></TextBlock>
<TextBlock Grid.Row="1" Text="{Binding Price}"></TextBlock>
<Image Height="100" Width="100" Source="{Binding Picture, Converter={StaticResource myImageConverter} }"></Image>
</Grid>
</Border>
</DataTemplate>
再给ListBox.ItemPanel(ListBox项的容器)制定一个模板:
<ItemsPanelTemplate x:Key="listItemPanelTemplate">
<toolkit:WrapPanel Width="500" />
</ItemsPanelTemplate>
样式如下:
<Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
然后在ListBox中使用:
<ListBox Name="lstProducts" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Grid.Row="0" Grid.Column="0" Height="400" ItemsPanel="{StaticResource listItemPanelTemplate}" ItemTemplate="{StaticResource listTemplate}" ItemContainerStyle="{StaticResource ListBoxItemStyle}" HorizontalContentAlignment="Stretch" SelectionChanged="lstProducts_SelectionChanged">
</ListBox>
可以看到给ItemsPanel制定的就是我们写的key为listItemPanelTemplate(就是ItemsPanelTemplate类型)的模板,ItemTemplate指定的就是listTemplate(就是DataTemplate
类型的模板),ItemContainerStyle指定的是自定义样式。
下面贴出完整的代码:
<UserControl xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" x:Class="ProSilverlight.DataTemplates.ListBoxTemplate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:binding="clr-namespace:ProSilverlight.DataBinding;assembly=ProSilverlight"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<binding:ImageConverter x:Name="myImageConverter"></binding:ImageConverter>
<Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
<DataTemplate x:Key="listTemplate" >
<Border Margin="5" Width="200" BorderBrush="SteelBlue" BorderThickness="1" CornerRadius="5">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding ProductName}"></TextBlock>
<TextBlock Grid.Row="1" Text="{Binding Price}"></TextBlock>
<Image Height="100" Width="100" Source="{Binding Picture, Converter={StaticResource myImageConverter} }"></Image>
</Grid>
</Border>
</DataTemplate>
<ItemsPanelTemplate x:Key="listItemPanelTemplate">
<toolkit:WrapPanel Width="500" />
</ItemsPanelTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition Width="5*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListBox Name="lstProducts" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Grid.Row="0" Grid.Column="0" Height="400" ItemsPanel="{StaticResource listItemPanelTemplate}" ItemTemplate="{StaticResource listTemplate}" ItemContainerStyle="{StaticResource ListBoxItemStyle}" HorizontalContentAlignment="Stretch" SelectionChanged="lstProducts_SelectionChanged">
</ListBox>
</Grid>
</UserControl>
其中的
<binding:ImageConverter x:Name="myImageConverter"></binding:ImageConverter>
为自定义的一个获取Image的Convert,代码如下:
Convert方法的代码也很简单,通过HtmlPage.Document.Document.Uri得到当前应用程序的根目录,然后通过拼凑字符串得到对应在web端的图片(也可以使用这个方式
去访问Web的Image在其他的功能中).
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Data;
using System.Windows.Browser;
using System.Windows.Media.Imaging;
namespace ProSilverlight.DataBinding
{
public class ImageConverter : IValueConverter
{
private string rootUri;
/// <summary>
/// 表示当前运行程序的根路径
/// </summary>
public string RootUri
{
get;
set;
}
public ImageConverter()
{
//得到当前网页的地址
string uri = HtmlPage.Document.DocumentUri.ToString();
//得到当前网页的根目录地址
rootUri = uri.Remove(uri.LastIndexOf('/'),uri.Length - uri.LastIndexOf('/'));
}
/// <summary>
/// 从源向Element发送数据经过的Convert方法
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string imageUri = rootUri + "/Img/" + value.ToString();
return new BitmapImage(new Uri(imageUri));
}
/// <summary>
/// 从Element向源提交数据经过的Convert方法
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
}
其实Template说白了就是修改当前Element对应的Template的部分,当前例子中分别修改了 ItemTemplate模板和ItemPanel模板,在模板中可以放置任意的Element,
当然该例子是一个很简单的模板的修改,更复杂的可以参看MSDN网站http://msdn.microsoft.com/zh-cn/library/cc278075%28v=VS.95%29.aspx