Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Issue #345 top/bottom flyouts

  • Loading branch information...
commit 5ce615d7d68591d6630dad53f3c2fcea7f06d0f3 1 parent f4c0dc6
Jan Karger authored shiftkey committed
View
66 FlyoutDemo/MainWindow.xaml
@@ -134,6 +134,59 @@
</ComboBox>
</StackPanel>
</Controls:Flyout>
+
+ <Controls:Flyout Header="Top"
+ Position="Top">
+ <StackPanel Margin="5,5,5,5"
+ HorizontalAlignment="Right"
+ Orientation="Horizontal"
+ Height="80">
+ <Button Foreground="{DynamicResource FlyoutWhiteBrush}"
+ Style="{DynamicResource MetroCircleButtonStyle}"
+ Height="40"
+ Width="40"
+ FontFamily="Segoe UI Symbol"
+ FontSize="16">
+ <Rectangle Width="20"
+ Height="20">
+ <Rectangle.Resources>
+ <SolidColorBrush x:Key="BlackBrush"
+ Color="{DynamicResource FlyoutWhiteColor}" />
+ </Rectangle.Resources>
+ <Rectangle.Fill>
+ <VisualBrush Stretch="Fill"
+ Visual="{StaticResource appbar_add}" />
+ </Rectangle.Fill>
+ </Rectangle>
+ </Button>
+ </StackPanel>
+ </Controls:Flyout>
+ <Controls:Flyout Header="Bottom"
+ Position="Bottom">
+ <StackPanel Margin="5,5,5,5"
+ HorizontalAlignment="Right"
+ Orientation="Horizontal"
+ Height="80">
+ <Button Foreground="{DynamicResource FlyoutWhiteBrush}"
+ Style="{DynamicResource MetroCircleButtonStyle}"
+ Height="40"
+ Width="40"
+ FontFamily="Segoe UI Symbol"
+ FontSize="16">
+ <Rectangle Width="20"
+ Height="20">
+ <Rectangle.Resources>
+ <SolidColorBrush x:Key="BlackBrush"
+ Color="{DynamicResource FlyoutWhiteColor}" />
+ </Rectangle.Resources>
+ <Rectangle.Fill>
+ <VisualBrush Stretch="Fill"
+ Visual="{StaticResource appbar_add}" />
+ </Rectangle.Fill>
+ </Rectangle>
+ </Button>
+ </StackPanel>
+ </Controls:Flyout>
</Controls:MetroWindow.Flyouts>
<Grid>
@@ -162,6 +215,19 @@
Content="Close" />
</StackPanel>
+ <StackPanel HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Margin="10">
+ <Button Click="ShowTop"
+ MinWidth="90"
+ Margin="2"
+ Content="Show Top" />
+ <Button Click="ShowBottom"
+ MinWidth="90"
+ Margin="2"
+ Content="Show Bottom" />
+ </StackPanel>
+
<StackPanel HorizontalAlignment="Right"
Margin="10">
<Button Click="ShowLeft"
View
8 FlyoutDemo/MainWindow.xaml.cs
@@ -29,6 +29,14 @@ public partial class MainWindow : MetroWindow
this.Flyouts[4].IsOpen = !this.Flyouts[4].IsOpen;
}
+ private void ShowTop(object sender, RoutedEventArgs e) {
+ this.Flyouts[5].IsOpen = !this.Flyouts[5].IsOpen;
+ }
+
+ private void ShowBottom(object sender, RoutedEventArgs e) {
+ this.Flyouts[6].IsOpen = !this.Flyouts[6].IsOpen;
+ }
+
private void CloseMe(object sender, RoutedEventArgs e) {
this.Close();
}
View
304 MahApps.Metro/Controls/Flyout.cs
@@ -1,135 +1,169 @@
-using System;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-
-namespace MahApps.Metro.Controls
-{
- [TemplatePart(Name = "PART_BackButton", Type = typeof(Button))]
- [TemplatePart(Name = "PART_Header", Type = typeof(ContentPresenter))]
- public class Flyout : ContentControl
- {
- public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(string), typeof(Flyout), new PropertyMetadata(default(string)));
- public static readonly DependencyProperty PositionProperty = DependencyProperty.Register("Position", typeof(Position), typeof(Flyout), new PropertyMetadata(Position.Left, PositionChanged));
- public static readonly DependencyProperty IsPinnableProperty = DependencyProperty.Register("IsPinnable", typeof(bool), typeof(Flyout), new PropertyMetadata(default(bool)));
- public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(Flyout), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsOpenedChanged));
- public static readonly DependencyProperty HeaderTemplateProperty = DependencyProperty.Register("HeaderTemplate", typeof(DataTemplate), typeof(Flyout));
-
- public DataTemplate HeaderTemplate
- {
- get { return (DataTemplate)GetValue(HeaderTemplateProperty); }
- set { SetValue(HeaderTemplateProperty, value); }
- }
-
- public bool IsOpen
- {
- get { return (bool)GetValue(IsOpenProperty); }
- set { SetValue(IsOpenProperty, value); }
- }
-
- public bool IsPinnable
- {
- get { return (bool)GetValue(IsPinnableProperty); }
- set { SetValue(IsPinnableProperty, value); }
- }
-
- public Position Position
- {
- get { return (Position)GetValue(PositionProperty); }
- set { SetValue(PositionProperty, value); }
- }
-
- public string Header
- {
- get { return (string)GetValue(HeaderProperty); }
- set { SetValue(HeaderProperty, value); }
- }
-
- private static void IsOpenedChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
- {
- var flyout = (Flyout)dependencyObject;
- VisualStateManager.GoToState(flyout, (bool) e.NewValue == false ? "Hide" : "Show", true);
- }
-
- private static void PositionChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
- {
- var flyout = (Flyout) dependencyObject;
- flyout.ApplyAnimation((Position)e.NewValue);
- }
-
- static Flyout()
- {
- DefaultStyleKeyProperty.OverrideMetadata(typeof(Flyout), new FrameworkPropertyMetadata(typeof(Flyout)));
- }
-
- public override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
- ApplyAnimation(Position);
- }
-
- internal void ApplyAnimation(Position position)
- {
- var root = (Grid)GetTemplateChild("root");
- if (root == null)
- return;
-
- var hideFrame = (EasingDoubleKeyFrame)GetTemplateChild("hideFrame");
- var showFrame = (EasingDoubleKeyFrame)GetTemplateChild("showFrame");
-
- if (hideFrame == null || showFrame == null)
- return;
-
- showFrame.Value = 0;
- root.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
-
- if (position == Position.Right)
- HorizontalAlignment = HorizontalAlignment.Right;
-
- if (position == Position.Right)
- {
- hideFrame.Value = root.DesiredSize.Width;
- root.RenderTransform = new TranslateTransform(root.DesiredSize.Width, 0);
- }
- else
- {
- hideFrame.Value = -root.DesiredSize.Width;
- root.RenderTransform = new TranslateTransform(-root.DesiredSize.Width, 0);
- }
- }
-
- protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
- {
- base.OnRenderSizeChanged(sizeInfo);
-
- if (!sizeInfo.WidthChanged) return;
-
- if (!IsOpen)
- {
- ApplyAnimation(Position);
- return;
- }
-
- var root = (Grid)GetTemplateChild("root");
- if (root == null)
- return;
-
- var hideFrame = (EasingDoubleKeyFrame)GetTemplateChild("hideFrame");
- var showFrame = (EasingDoubleKeyFrame)GetTemplateChild("showFrame");
-
- if (hideFrame == null || showFrame == null)
- return;
-
- showFrame.Value = 0;
- if (Position == Position.Right)
- {
- hideFrame.Value = root.DesiredSize.Width;
- }
- else
- {
- hideFrame.Value = -root.DesiredSize.Width;
- }
- }
- }
-}
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+
+namespace MahApps.Metro.Controls
+{
+ [TemplatePart(Name = "PART_BackButton", Type = typeof(Button))]
+ [TemplatePart(Name = "PART_Header", Type = typeof(ContentPresenter))]
+ public class Flyout : ContentControl
+ {
+ public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(string), typeof(Flyout), new PropertyMetadata(default(string)));
+ public static readonly DependencyProperty PositionProperty = DependencyProperty.Register("Position", typeof(Position), typeof(Flyout), new PropertyMetadata(Position.Left, PositionChanged));
+ public static readonly DependencyProperty IsPinnableProperty = DependencyProperty.Register("IsPinnable", typeof(bool), typeof(Flyout), new PropertyMetadata(default(bool)));
+ public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(Flyout), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsOpenedChanged));
+ public static readonly DependencyProperty HeaderTemplateProperty = DependencyProperty.Register("HeaderTemplate", typeof(DataTemplate), typeof(Flyout));
+
+ public DataTemplate HeaderTemplate
+ {
+ get { return (DataTemplate)GetValue(HeaderTemplateProperty); }
+ set { SetValue(HeaderTemplateProperty, value); }
+ }
+
+ public bool IsOpen
+ {
+ get { return (bool)GetValue(IsOpenProperty); }
+ set { SetValue(IsOpenProperty, value); }
+ }
+
+ public bool IsPinnable
+ {
+ get { return (bool)GetValue(IsPinnableProperty); }
+ set { SetValue(IsPinnableProperty, value); }
+ }
+
+ public Position Position
+ {
+ get { return (Position)GetValue(PositionProperty); }
+ set { SetValue(PositionProperty, value); }
+ }
+
+ public string Header
+ {
+ get { return (string)GetValue(HeaderProperty); }
+ set { SetValue(HeaderProperty, value); }
+ }
+
+ private static void IsOpenedChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
+ {
+ var flyout = (Flyout)dependencyObject;
+ VisualStateManager.GoToState(flyout, (bool) e.NewValue == false ? "Hide" : "Show", true);
+ }
+
+ private static void PositionChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
+ {
+ var flyout = (Flyout) dependencyObject;
+ flyout.ApplyAnimation((Position)e.NewValue);
+ }
+
+ static Flyout()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(Flyout), new FrameworkPropertyMetadata(typeof(Flyout)));
+ }
+
+ public override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+ ApplyAnimation(Position);
+ }
+
+ internal void ApplyAnimation(Position position)
+ {
+ var root = (Grid)GetTemplateChild("root");
+ if (root == null)
+ return;
+
+ var hideFrame = (EasingDoubleKeyFrame)GetTemplateChild("hideFrame");
+ var hideFrameY = (EasingDoubleKeyFrame)GetTemplateChild("hideFrameY");
+ var showFrame = (EasingDoubleKeyFrame)GetTemplateChild("showFrame");
+ var showFrameY = (EasingDoubleKeyFrame)GetTemplateChild("showFrameY");
+
+ if (hideFrame == null || showFrame == null || hideFrameY == null || showFrameY == null)
+ return;
+
+ if (Position == Position.Left || Position == Position.Right)
+ showFrame.Value = 0;
+ if (Position == Position.Top || Position == Position.Bottom)
+ showFrameY.Value = 0;
+ root.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
+
+ switch (position)
+ {
+ default:
+ case Position.Left:
+ HorizontalAlignment = HorizontalAlignment.Left;
+ VerticalAlignment = VerticalAlignment.Stretch;
+ hideFrame.Value = -root.DesiredSize.Width;
+ root.RenderTransform = new TranslateTransform(-root.DesiredSize.Width, 0);
+ break;
+ case Position.Right:
+ HorizontalAlignment = HorizontalAlignment.Right;
+ VerticalAlignment = VerticalAlignment.Stretch;
+ hideFrame.Value = root.DesiredSize.Width;
+ root.RenderTransform = new TranslateTransform(root.DesiredSize.Width, 0);
+ break;
+ case Position.Top:
+ HorizontalAlignment = HorizontalAlignment.Stretch;
+ VerticalAlignment = VerticalAlignment.Top;
+ hideFrameY.Value = -root.DesiredSize.Height;
+ root.RenderTransform = new TranslateTransform(0, -root.DesiredSize.Height);
+ break;
+ case Position.Bottom:
+ HorizontalAlignment = HorizontalAlignment.Stretch;
+ VerticalAlignment = VerticalAlignment.Bottom;
+ hideFrameY.Value = root.DesiredSize.Height;
+ root.RenderTransform = new TranslateTransform(0, root.DesiredSize.Height);
+ break;
+ }
+ }
+
+ protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
+ {
+ base.OnRenderSizeChanged(sizeInfo);
+
+ if (!sizeInfo.WidthChanged || !sizeInfo.HeightChanged) return;
+
+ if (!IsOpen)
+ {
+ ApplyAnimation(Position);
+ return;
+ }
+
+ var root = (Grid)GetTemplateChild("root");
+ if (root == null)
+ return;
+
+ var hideFrame = (EasingDoubleKeyFrame)GetTemplateChild("hideFrame");
+ var hideFrameY = (EasingDoubleKeyFrame)GetTemplateChild("hideFrameY");
+ var showFrame = (EasingDoubleKeyFrame)GetTemplateChild("showFrame");
+ var showFrameY = (EasingDoubleKeyFrame)GetTemplateChild("showFrameY");
+
+ if (hideFrame == null || showFrame == null || hideFrameY == null || showFrameY == null)
+ return;
+
+ if (Position == Position.Left || Position == Position.Right)
+ showFrame.Value = 0;
+ if (Position == Position.Top || Position == Position.Bottom)
+ showFrameY.Value = 0;
+
+ switch (Position)
+ {
+ default:
+ case Position.Left:
+ hideFrame.Value = -root.DesiredSize.Width;
+ break;
+ case Position.Right:
+ hideFrame.Value = root.DesiredSize.Width;
+ break;
+ case Position.Top:
+ hideFrameY.Value = -root.DesiredSize.Height;
+ break;
+ case Position.Bottom:
+ hideFrameY.Value = root.DesiredSize.Height;
+ break;
+ }
+ }
+ }
+}
View
4 MahApps.Metro/Controls/Position.cs
@@ -3,6 +3,8 @@ namespace MahApps.Metro.Controls
public enum Position
{
Left,
- Right
+ Right,
+ Top,
+ Bottom
}
}
View
73 MahApps.Metro/Themes/Flyout.xaml
@@ -10,7 +10,9 @@
<DataTemplate x:Key="HeaderTemplate"
x:Shared="False">
- <DockPanel Margin="10"
+ <DockPanel x:Name="dpHeader"
+ Margin="10"
+ VerticalAlignment="Top"
LastChildFill="True">
<Button x:Name="nav"
DockPanel.Dock="Left"
@@ -75,14 +77,32 @@
</Setter.Value>
</Setter>
</DataTrigger>
+ <DataTrigger Binding="{Binding Position, RelativeSource={RelativeSource AncestorType={x:Type Controls:Flyout}}}"
+ Value="Top">
+ <Setter TargetName="nav"
+ Property="LayoutTransform">
+ <Setter.Value>
+ <RotateTransform Angle="-90" />
+ </Setter.Value>
+ </Setter>
+ <Setter TargetName="dpHeader" Property="VerticalAlignment" Value="Bottom" />
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Position, RelativeSource={RelativeSource AncestorType={x:Type Controls:Flyout}}}"
+ Value="Bottom">
+ <Setter TargetName="nav"
+ Property="LayoutTransform">
+ <Setter.Value>
+ <RotateTransform Angle="90" />
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<ControlTemplate x:Key="FlyoutTemplate"
TargetType="{x:Type Controls:Flyout}">
<Grid x:Name="root"
- Background="{TemplateBinding Background}"
- HorizontalAlignment="Left">
+ Background="{TemplateBinding Background}">
<Grid.RenderTransform>
<TranslateTransform />
</Grid.RenderTransform>
@@ -95,28 +115,51 @@
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
Storyboard.TargetName="root">
<EasingDoubleKeyFrame KeyTime="00:00:00.500"
- Value="1"
+ Value="0"
x:Name="hideFrame">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
+ <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
+ Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
+ Storyboard.TargetName="root">
+ <EasingDoubleKeyFrame KeyTime="00:00:00.500"
+ Value="0"
+ x:Name="hideFrameY">
+ <EasingDoubleKeyFrame.EasingFunction>
+ <CubicEase EasingMode="EaseOut" />
+ </EasingDoubleKeyFrame.EasingFunction>
+ </EasingDoubleKeyFrame>
+ </DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Show">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
+ x:Name="trabslateShow"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
Storyboard.TargetName="root">
<EasingDoubleKeyFrame KeyTime="00:00:00.600"
- Value="1"
+ Value="0"
x:Name="showFrame">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
+ <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
+ Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
+ Storyboard.TargetName="root">
+ <EasingDoubleKeyFrame KeyTime="00:00:00.600"
+ Value="0"
+ x:Name="showFrameY">
+ <EasingDoubleKeyFrame.EasingFunction>
+ <CubicEase EasingMode="EaseOut" />
+ </EasingDoubleKeyFrame.EasingFunction>
+ </EasingDoubleKeyFrame>
+ </DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
@@ -131,6 +174,26 @@
</ContentPresenter>
</DockPanel>
</Grid>
+ <ControlTemplate.Triggers>
+ <DataTrigger Binding="{Binding Position, RelativeSource={RelativeSource Self}}"
+ Value="Top">
+ <Setter TargetName="PART_Header"
+ Property="DockPanel.Dock"
+ Value="Left" />
+ <Setter TargetName="PART_Content"
+ Property="DockPanel.Dock"
+ Value="Right" />
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Position, RelativeSource={RelativeSource Self}}"
+ Value="Bottom">
+ <Setter TargetName="PART_Header"
+ Property="DockPanel.Dock"
+ Value="Left" />
+ <Setter TargetName="PART_Content"
+ Property="DockPanel.Dock"
+ Value="Right" />
+ </DataTrigger>
+ </ControlTemplate.Triggers>
</ControlTemplate>
<Style TargetType="{x:Type Controls:Flyout}">
Please sign in to comment.
Something went wrong with that request. Please try again.