動態的改變Row或Column的大小應該是常常要用到的功能,可是Silverlight又不能像WPF一樣自訂一個新的GridLength動畫出來,那~~只好用騙的了!!
我們可以透過一個型別為double的DependencyProperty來套用DoubleAnimation,並且在它的值改變的時候,利用程式將它轉為GridLength,這樣就可以做到我們要的效果了。
動態的改變Row或Column的大小應該是常常要用到的功能,可是Silverlight又不能像WPF一樣自訂一個新的GridLength動畫出來,那~~只好用騙的了!!
我們可以透過一個型別為double的DependencyProperty來套用DoubleAnimation,並且在它的值改變的時候,利用程式將它轉為GridLength,這樣就可以做到我們要的效果了。
來個範例:
程式碼如下:
<UserControl
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"
mc:Ignorable="d"
x:Name="MainPageControl"
x:Class="Sl_GridLengthAnimation.MainPage"
d:DesignWidth="640" d:DesignHeight="480"
Width="Auto" Height="Auto">
<UserControl.Resources>
<Storyboard x:Key="ShowColumn">
<DoubleAnimation Storyboard.TargetName="MainPageControl" Storyboard.TargetProperty="GridWidth" From="0" To="200"
BeginTime="0:0:0" Duration="0:0:.5" Completed="DoubleAnimation_Completed">
<DoubleAnimation.EasingFunction>
<BounceEase EasingMode="EaseOut"></BounceEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Key="HideColumn">
<DoubleAnimation Storyboard.TargetName="MainPageControl" Storyboard.TargetProperty="GridWidth" From="200" To="0"
BeginTime="0:0:0" Duration="0:0:.5" Completed="DoubleAnimation_Completed">
<DoubleAnimation.EasingFunction>
<BounceEase EasingMode="EaseOut"></BounceEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="column1" Width="200"/>
<ColumnDefinition Width="0.75*"/>
</Grid.ColumnDefinitions>
<Button Name="btnShowHide" Content="Hide Column" HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto"
Grid.Column="1" Margin="0,0,8,8" Click="btnShowHide_Click" RenderTransformOrigin="0.5,0.5"
Padding="10">
<Button.RenderTransform>
<CompositeTransform/>
</Button.RenderTransform>
</Button>
<Rectangle Fill="#FF29A7FF"/>
<TextBlock Text="我在Column1裡面" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16" />
</Grid>
</UserControl>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
namespace Sl_GridLengthAnimation
{
public partial class MainPage : UserControl
{
private bool _isColumnCollapsed = false;
public MainPage()
{
InitializeComponent();
}
public static readonly DependencyProperty GridWidthProperty = DependencyProperty.Register( "GridWidth" , typeof( double ) , typeof( MainPage ) ,
new PropertyMetadata( ( double ) 100.00 , OnGridWidthPropertyChanged ) );
public double GridWidth
{
get
{
return ( double ) GetValue( GridWidthProperty );
}
set
{
SetValue( GridWidthProperty , value );
}
}
private static void OnGridWidthPropertyChanged( DependencyObject obj , DependencyPropertyChangedEventArgs args )
{
if( obj != null )
{
MainPage mainPage = obj as MainPage;
mainPage.column1.Width = new GridLength( mainPage.GridWidth , GridUnitType.Pixel );
}
}
private void btnShowHide_Click( object sender , System.Windows.RoutedEventArgs e )
{
btnShowHide.IsEnabled = false;
Storyboard storyboard = ( this._isColumnCollapsed == true ) ? this.Resources[ "ShowColumn" ] as Storyboard : this.Resources[ "HideColumn" ] as Storyboard;
storyboard.Stop();
storyboard.Begin();
}
private void DoubleAnimation_Completed( object sender , EventArgs e )
{
this._isColumnCollapsed = !this._isColumnCollapsed;
btnShowHide.IsEnabled = true;
btnShowHide.Content = new TextBlock { Text = ( this._isColumnCollapsed == true ) ? "Show Column" : "Hide Column" };
}
}
}
不過,這樣做有一個很大的缺點,就是在Blend中想編輯該Storyboard的時候,Blend會認為XAML有誤,而沒辦法編輯,只能乖乖的去Key XAML了。
雖然不是很完美,但是這樣至少還是可以達到動畫切換Grid中Row和Column大小的效果,在研究出更好的方式前,就先將就著用吧 >"<
另外一併附上專案原始檔,請服用: