Toolkit(http://silverlight.codeplex.com/)中有一个不错的控件:HubTile。
但这个控件只能用于173*173的Tile,如果想放其他尺寸的的就麻烦一些了(一行并排3个显示的Tile)
下面是实现可重定义tile大小的完整代码
步骤1:写一个Converner类,用于缩放double类型的数值
需要命名空间:
using System.Globalization;
using System.Windows.Data;
public class DoubleScaleConverner : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double && targetType == typeof(double))
{
double dbOrig = (double)value;
if (parameter is string)
{
double dbParam;
if (double.TryParse((parameter as string), out dbParam))
{
return Math.Round(dbOrig * dbParam);
}
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
2. ResourceDictionary文件中,将converner声明出来
xmlns:my="clr-namespace:HubTileTest"
<my:DoubleScaleConverner x:Key="doubleScaleConverner" />
3. 用blend生成hubtile的style,并做修改成这样
<Style x:Key="customHubTileStyle" TargetType="toolkit:HubTile">
<Style.Setters>
<Setter Property="Height" Value="173"/>
<Setter Property="Width" Value="173"/>
<Setter Property="Background" Value="{StaticResource PhoneAccentBrush}"/>
<Setter Property="Foreground" Value="#FFFFFFFF"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:HubTile">
<StackPanel x:Name="Viewport"
Height="{TemplateBinding Height}" Width="{TemplateBinding Width}">
<StackPanel.Resources>
<CubicEase EasingMode="EaseOut" x:Key="HubTileEaseOut"/>
</StackPanel.Resources>
<StackPanel.Projection>
<PlaneProjection CenterOfRotationY="0.25" x:Name="ViewportProjection"/>
</StackPanel.Projection>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ImageStates">
<VisualStateGroup.Transitions>
<VisualTransition x:Name="ExpandedToSemiexpanded"
From="Expanded" To="Semiexpanded"
GeneratedDuration="0:0:0.85">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="TitlePanel">
<EasingDoubleKeyFrame KeyTime="0:0:0.0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=-1}" EasingFunction="{StaticResource HubTileEaseOut}"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.85" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=-0.45665}" EasingFunction="{StaticResource HubTileEaseOut}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="RotationX"
Storyboard.TargetName="ViewportProjection">
<EasingDoubleKeyFrame KeyTime="0:0:0.0" Value="0.0" EasingFunction="{StaticResource HubTileEaseOut}"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition x:Name="SemiexpandedToCollapsed"
From="Semiexpanded" To="Collapsed"
GeneratedDuration="0:0:0.85">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="TitlePanel">
<EasingDoubleKeyFrame KeyTime="0:0:0.0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=-0.45665}" EasingFunction="{StaticResource HubTileEaseOut}"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.85" Value="0.0" EasingFunction="{StaticResource HubTileEaseOut}"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition x:Name="CollapsedToExpanded"
From="Collapsed" To="Expanded"
GeneratedDuration="0:0:0.85">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="TitlePanel">
<EasingDoubleKeyFrame KeyTime="0:0:0.0" Value="0.0" EasingFunction="{StaticResource HubTileEaseOut}"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.85" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=-1}" EasingFunction="{StaticResource HubTileEaseOut}"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition x:Name="ExpandedToFlipped"
From="Expanded" To="Flipped"
GeneratedDuration="0:0:0.85">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="TitlePanel">
<EasingDoubleKeyFrame KeyTime="0:0:0.0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=-1}" EasingFunction="{StaticResource HubTileEaseOut}"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="Image">
<DiscreteObjectKeyFrame KeyTime="0:0:0.185" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="RotationX"
Storyboard.TargetName="ViewportProjection">
<EasingDoubleKeyFrame KeyTime="0:0:0.0" Value="0.0" EasingFunction="{StaticResource HubTileEaseOut}"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.85" Value="180.0" EasingFunction="{StaticResource HubTileEaseOut}"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition x:Name="FlippedToExpanded"
From="Flipped" To="Expanded"
GeneratedDuration="0:0:0.85">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="TitlePanel">
<EasingDoubleKeyFrame KeyTime="0:0:0.0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=-1}" EasingFunction="{StaticResource HubTileEaseOut}"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="Image">
<DiscreteObjectKeyFrame KeyTime="0:0:0.185" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="RotationX"
Storyboard.TargetName="ViewportProjection">
<EasingDoubleKeyFrame KeyTime="0:0:0.0" Value="180.0" EasingFunction="{StaticResource HubTileEaseOut}"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.85" Value="360.0" EasingFunction="{StaticResource HubTileEaseOut}"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualStateGroup.States>
<VisualState x:Name="Expanded">
<Storyboard>
<DoubleAnimation Duration="0" To="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=-1}"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="TitlePanel"/>
<DoubleAnimation Duration="0" To="0.0"
Storyboard.TargetProperty="RotationX"
Storyboard.TargetName="ViewportProjection"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="Image">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Semiexpanded">
<Storyboard>
<DoubleAnimation Duration="0" To="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=-0.45665}"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="TitlePanel"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Collapsed"/>
<VisualState x:Name="Flipped">
<Storyboard>
<DoubleAnimation Duration="0" To="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=-1}"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="TitlePanel"/>
<DoubleAnimation Duration="0" To="180.0"
Storyboard.TargetProperty="RotationX"
Storyboard.TargetName="ViewportProjection"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="Image">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup.States>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="TitlePanel"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=2}"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform/>
</Grid.RenderTransform>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.Row="0"
Background="{TemplateBinding Background}">
<TextBlock VerticalAlignment="Bottom"
Margin="10,0,0,6"
Text="{TemplateBinding Title}"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=0.22}"
Foreground="{TemplateBinding Foreground}"
TextWrapping="NoWrap"
LineStackingStrategy="BlockLineHeight"
LineHeight="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height, Converter={StaticResource doubleScaleConverner}, ConverterParameter=0.20}">
</TextBlock>
</Border>
<Grid x:Name="BackPanel"
Grid.Row="1"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}"
Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.Projection>
<PlaneProjection CenterOfRotationY="0.5" RotationX="180"/>
</Grid.Projection>
<TextBlock x:Name="NotificationBlock" Grid.Row="0"
Margin="8,8,0,6"
Text="{TemplateBinding Notification}"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeLarge}"
Foreground="{TemplateBinding Foreground}"
TextWrapping="NoWrap"
LineStackingStrategy="BlockLineHeight"
LineHeight="32"/>
<TextBlock x:Name="MessageBlock" Grid.Row="0"
Margin="10,10,10,6"
Text="{TemplateBinding Message}"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{TemplateBinding Foreground}"
TextWrapping="Wrap"
LineStackingStrategy="BlockLineHeight"
LineHeight="23.333"/>
<TextBlock x:Name="BackTitleBlock" Grid.Row="1"
VerticalAlignment="Bottom"
Margin="10,0,0,6"
FontFamily="{StaticResource PhoneFontFamilySemiBold}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{TemplateBinding Foreground}"
TextWrapping="NoWrap"/>
</Grid>
<Image x:Name="Image" Grid.Row="1"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}"
Stretch="UniformToFill"
Source="{TemplateBinding Source}"/>
</Grid>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
4. 如果要使用一个136*136的tile,这样写个样式就行了
<Style x:Key="smallTileStyle" TargetType="toolkit:HubTile" BasedOn="{StaticResource customHubTileStyle}">
<Setter Property="Height" Value="136" />
<Setter Property="Width" Value="136" />
<Setter Property="Background" Value="Purple" />
</Style>
