<mah:MetroWindow x:Class="MyControlsTest.MainWindow"
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:local="clr-namespace:MyControlsTest"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
mc:Ignorable="d"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
Title="MainWindow" SizeToContent="WidthAndHeight"
Background="Transparent"
UseNoneWindowStyle="True"
AllowsTransparency="True"
BorderThickness="0" PreviewMouseDown="MetroWindow_PreviewMouseDown" PreviewMouseMove="MetroWindow_PreviewMouseMove" PreviewMouseLeftButtonUp="MetroWindow_PreviewMouseLeftButtonUp">
<mah:MetroWindow.Resources>
<Storyboard x:Key="ExpandStoryboard">
<DoubleAnimation
Storyboard.TargetName="CtrlGrid"
Storyboard.TargetProperty="Width"
From="0"
To="100"
Duration="0:0:0.2"
/>
</Storyboard>
<Storyboard x:Key="CollapseStoryboard">
<DoubleAnimation
Storyboard.TargetName="CtrlGrid"
Storyboard.TargetProperty="Width"
From="100"
To="0"
Duration="0:0:0.2"
/>
</Storyboard>
<Storyboard x:Key="IconStoryboard">
<DoubleAnimation
Storyboard.TargetName="PackIconFileIcon"
Storyboard.TargetProperty="(iconPacks:PackIconFileIcons.RotationAngle)"
From="0"
To="360"
Duration="0:0:0.3"
/>
</Storyboard>
</mah:MetroWindow.Resources>
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition x:Name="column2" Width="5*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ToggleButton x:Name="toggleBtn" VerticalAlignment="Top" Width="30" Height="30" Margin="0,0,0,0">
<iconPacks:PackIconFeatherIcons Kind="Star" x:Name="PackIconFileIcon" />
</ToggleButton>
<Grid x:Name="CtrlGrid" Width="0" Grid.Column="1" HorizontalAlignment="Left">
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding AddButtonCommand}" Width="25" Height="25" BorderBrush="#FFE2E6BE" Foreground="#FFFBF9F9" Padding="0,0,0,0" SnapsToDevicePixels="True" mah:ControlsHelper.ContentCharacterCasing="Normal" Background="#FF5C6969" Margin="0,0,1,0" >
<iconPacks:PackIconFeatherIcons Kind="Sunrise" />
</Button>
<Button Command="{Binding ControlButtonCommand}" Width="25" Height="25" BorderBrush="#FFE2E6BE" Foreground="#FFFBF9F9" Padding="0,0,0,0" SnapsToDevicePixels="True" mah:ControlsHelper.ContentCharacterCasing="Normal" Background="#FF5C6969">
<iconPacks:PackIconFeatherIcons Kind="Sunset" />
</Button>
</StackPanel>
<ItemsControl x:Name="ItemsCtrl" ItemsSource="{Binding CmdButtons}" IsEnabled="True" Grid.Row="1" Width="50" HorizontalAlignment="Left" >
<ItemsControl.Items>
<Button Content="1"></Button>
<Button Content="1"></Button>
<Button Content="1"></Button>
</ItemsControl.Items>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding CmdButtonName}" Command="{Binding ItemsBtnCommand}" CommandParameter="{Binding Id}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Grid>
</mah:MetroWindow>
动画概述
代码中定义了三个 Storyboard,每个 Storyboard 包含一个 DoubleAnimation,用于创建不同的动画效果:
- ExpandStoryboard: 用于展开 CtrlGrid 的宽度。
- CollapseStoryboard: 用于折叠 CtrlGrid 的宽度。
- IconStoryboard: 用于旋转 PackIconFileIcon 图标。
代码解析
- ExpandStoryboard
<Storyboard x:Key="ExpandStoryboard">
<DoubleAnimation
Storyboard.TargetName="CtrlGrid"
Storyboard.TargetProperty="Width"
From="0"
To="100"
Duration="0:0:0.2"
/>
</Storyboard>
Storyboard.TargetName
: 指定动画的目标对象,这里是 CtrlGrid。
Storyboard.TargetProperty
: 指定动画的目标属性,这里是 Width。
From
: 动画的起始值,这里是 0。
To
: 动画的结束值,这里是 100。
Duration
: 动画的持续时间,这里是 0.2 秒。
这个故事板的作用是将 CtrlGrid 的宽度从 0 展开到 100。
- CollapseStoryboard
<Storyboard x:Key="CollapseStoryboard">
<DoubleAnimation
Storyboard.TargetName="CtrlGrid"
Storyboard.TargetProperty="Width"
From="100"
To="0"
Duration="0:0:0.2"
/>
</Storyboard>
Storyboard.TargetName
: 指定动画的目标对象,这里是 CtrlGrid。
Storyboard.TargetProperty
: 指定动画的目标属性,这里是 Width。
From
: 动画的起始值,这里是 100。
To
: 动画的结束值,这里是 0。
Duration
: 动画的持续时间,这里是 0.2 秒。
这个故事板的作用是将 CtrlGrid 的宽度从 100 折叠到 0。
- IconStoryboard
<Storyboard x:Key="IconStoryboard">
<DoubleAnimation
Storyboard.TargetName="PackIconFileIcon"
Storyboard.TargetProperty="(iconPacks:PackIconFileIcons.RotationAngle)"
From="0"
To="360"
Duration="0:0:0.3"
/>
</Storyboard>
Storyboard.TargetName
: 指定动画的目标对象,这里是 PackIconFileIcon。
Storyboard.TargetProperty
: 指定动画的目标属性,这里是 (iconPacks:PackIconFileIcons.RotationAngle)
,表示旋转角度。
From
: 动画的起始值,这里是 0。
To
: 动画的结束值,这里是 360,表示旋转一圈。
Duration
: 动画的持续时间,这里是 0.3 秒。
这个故事板的作用是将 PackIconFileIcon 图标旋转 360 度。
后台函数
public partial class MainWindow : MetroWindow
{
public ObservableCollection<CmdButton> cmdButtons;
public ObservableCollection<CmdButton> CmdButtons
{
get
{
return cmdButtons;
}
set
{
cmdButtons = value;
}
}
public MainWindow()
{
InitializeComponent();
toggleBtn.AddHandler(Button.MouseLeftButtonUpEvent, new MouseButtonEventHandler(this.toggleBtn_MouseLeftButtonUp), true);
toggleBtn.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.toggleBtn_MouseLeftButtonDown), true);
this.Left = SystemParameters.PrimaryScreenWidth / 5 * 4;
this.Top = SystemParameters.PrimaryScreenHeight / 5;
}
private void toggleBtn_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_pressedPosition2 = e.GetPosition(this);
}
private void toggleBtn_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Released && _pressedPosition2 == e.GetPosition(this))
{
if (toggleBtn.IsChecked == true)
{
//ItemsCtrl.Visibility = Visibility.Visible;
var expandStoryboard = (Storyboard)FindResource("ExpandStoryboard");
expandStoryboard.Begin();
var IconStoryboard = (Storyboard)FindResource("IconStoryboard");
IconStoryboard.Begin();
}
else
{
var collapseStoryboard = (Storyboard)FindResource("CollapseStoryboard");
collapseStoryboard.Begin();
var IconStoryboard = (Storyboard)FindResource("IconStoryboard");
IconStoryboard.Begin();
//ItemsCtrl.Visibility = Visibility.Hidden;
}
}
}
Point _pressedPosition2;
Point _pressedPosition;
bool _isDragMoved = false;
private void MetroWindow_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
_pressedPosition = e.GetPosition(this);
}
private void MetroWindow_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Pressed && _pressedPosition != e.GetPosition(this))
{
_isDragMoved = true;
DragMove();
toggleBtn.IsChecked = false;
}
}
private void MetroWindow_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_isDragMoved)
{
_isDragMoved = false;
e.Handled = true;
toggleBtn.IsChecked = false;
}
}
}