Quickstart: Adding a Flyout (XAML)
[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]
Learn how to use a Flyout to temporarily show UI relevant to your users' context. Use it to collect input from the user, show more details about an item, or ask the user to confirm an action.
Prerequisites
- Windows 8.1 or Windows Phone 8.1
- Microsoft Visual Studio 2013
- We assume that you can add controls to a basic Windows Runtime app using C++, C#, or Visual Basic. For instructions on adding a control, see Quickstart: Adding controls and handling events.
When to use a flyout
A Flyout control displays lightweight UI (called a flyout) that either is informational or requires user interaction. Unlike a dialog, a flyout can be lightly dismissed by clicking or tapping outside it. A flyout should be shown only in response to a user tap or click. Don't dismiss a flyout programmatically unless the user has pressed a command button or selected a menu item in the flyout. The user can dismiss a flyout at any time without performing an action by tapping or clicking outside of it, or by pressing ESC.
Use a flyout for:
- Collecting information—if the user selects an action that requires more input, such as choosing an option or typing information, you can place that UI in a flyout to keep the user in their original context.
- Displaying more info—show more details about an item on the screen that the user is interested in.
- Warnings and confirmations—warn the user before they take a potentially destructive action, and let them confirm the action.
To show a menu of items that the user can select from, use a MenuFlyout instead. See Quickstart: Adding a MenuFlyout.
Don't use a Flyout instead of a ToolTip or context menu. Use a ToolTip to show a short description that hides after a specified time. Use a context menu for contextual actions related to text selection, like copy and paste.
For more info, see Guidelines and checklist for Flyouts.
Using a Flyout with a Button control
It’s common to attach a flyout to a button, so the Button control has a Flyout property to simplify attaching and opening a Flyout control. A flyout attached to a button opens automatically when the user clicks the button. You don't need to handle any events to open the flyout. (This includes controls derived from Button, like AppBarButton.)
This example shows a Flyout attached to a Button. The flyout warns the user that items will be permanently deleted, and lets the user confirm or cancel the deletion.
Declare a Button control in Extensible Application Markup Language (XAML).
Declare the contents of the flyout. The flyout can have only one content item, so complex UI must be wrapped in a root panel, such as a StackPanel or Grid.
Handle the Click event of the button inside the flyout to perform the action when the user confirms it.
When the user confirms the action, hide the flyout programmatically by calling the Hide method.
To cancel the action, the user can dismiss the flyout by tapping outside it or pressing ESC.
<Button x:Name="DeleteButton" Content="Empty cart">
<Button.Flyout>
<Flyout>
<StackPanel>
<TextBlock Style="{StaticResource BaseTextBlockStyle}">
All items will be permanently removed from your cart.
</TextBlock>
<Button Click="DeleteConfirmation_Click" Margin="0,5,0,0">
Empty my cart
</Button>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
private void DeleteConfirmation_Click(object sender, RoutedEventArgs e)
{
// Dismiss the Flyout after the action is confirmed.
DeleteButton.Flyout.Hide();
// Delete content of cart...
}
When the user clicks the button, the open flyout looks like this. The user can click the button inside the flyout to proceed, or click outside the flyout to dismiss it and cancel the action.
Using a Flyout with other UI elements
You can attach a Flyout control to any FrameworkElement object by using the FlyoutBase.AttachedFlyout attached property. If you do so, you must respond to an interaction on the FrameworkElement, such as the Tapped event, and open the Flyout in your code.
This example shows how to use a shared Flyout to show a preview when a user taps an Image.
- Declare the Flyout as a StaticResource and give it an x:Key attribute value.
- For each element that shares this Flyout, set the FlyoutBase.AttachedFlyout attached property to the Flyout resource.
- Handle the Tapped event for each element that uses the flyout. In the event handler, call the FlyoutBase.AttachedFlyout method and pass the tapped element (
sender
) as the parameter.
<!-- Declare the shared flyout as a resource. -->
<Page.Resources>
<Flyout x:Key="ImagePreviewFlyout" Placement="Right">
<!-- The DataContext of the Image that the flyout is attached to must be the Image's Source. -->
<Image Source="{Binding Path=Source}" MaxHeight="400" MaxWidth="400" Stretch="Uniform"/>
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="ScrollViewer.ZoomMode" Value="Enabled"/>
<Setter Property="Background" Value="Black"/>
<Setter Property="BorderBrush" Value="Gray"/>
<Setter Property="BorderThickness" Value="5"/>
<Setter Property="MinHeight" Value="300"/>
<Setter Property="MinWidth" Value="300"/>
</Style>
</Flyout.FlyoutPresenterStyle>
</Flyout>
</Page.Resources>
...
<!-- Assign the flyout to each element that shares it. -->
<StackPanel>
<Image Source="Assets/cliff.jpg" Width="50" Height="50" Margin="10" Tapped="Image_Tapped"
FlyoutBase.AttachedFlyout="{StaticResource ImagePreviewFlyout}"
DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
<Image Source="Assets/grapes.jpg" Width="50" Height="50" Margin="10" Tapped="Image_Tapped"
FlyoutBase.AttachedFlyout="{StaticResource ImagePreviewFlyout}"
DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
<Image Source="Assets/rainier.jpg" Width="50" Height="50" Margin="10" Tapped="Image_Tapped"
FlyoutBase.AttachedFlyout="{StaticResource ImagePreviewFlyout}"
DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
</StackPanel>
...
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
}
When a user taps a small image, a large preview is shown in a flyout like this.
Showing and hiding a Flyout
Only one flyout can be open at a time. When a flyout opens, any other flyout that's already open is automatically dismissed.
As shown in the first example in this tutorial, you should dismiss a flyout by calling its Hide method when an action is committed.
DeleteButton.Flyout.Hide();
Don't dismiss a flyout programmatically unless the user has pressed a command button or selected a menu item in the flyout. You shouldn't dismiss the flyout if the user has only toggled a setting, for example. The flyout is dismissed automatically when an action is cancelled by the user clicking outside of it.
A flyout that's attached to a Button is shown automatically when the button is clicked. When a flyout is attached to any other element, you must open the flyout in response to an event, typically a Tapped event. In the event handler, call the FlyoutBase.ShowAttachedFlyout method. This is shown in the second example in this tutorial.
FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
A flyout is typically positioned near the element it's attached to in order to keep the user in their current context. If it makes sense to position the flyout near a related element other than the element that invoked it, you can call ShowAt. For more info and examples, see the ShowAt method.
Sharing a Flyout
A Flyout declared in XAML can be declared either inline or as a resource that can be shared. The first example in this tutorial shows how to declare a Flyout inline in a button's XAML. This Flyout can only be attached to the Button where it's declared.
The second example in this tutorial shows how to declare a Flyout as a StaticResource and use it with several different elements. In this example, the DataContext of the main Image is set to itself.
<Image DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
The Flyout inherits the DataContext of its anchor element, so you can bind the Source property of the Image in the Flyout to the Source property of the DataContext. In this way, a single Flyout shows a preview of whichever Image the user taps.
<Flyout>
<Image Source="{Binding Path=Source}"/>
...
</Flyout>
This example shows the syntax for declaring a Flyout inline or as a resource that can be shared.
<!-- Inline flyouts -->
<!-- Flyout declared inline on a Button -->
<Button>
<Button.Flyout>
<Flyout>
<!-- Flyout content -->
</Flyout>
</Button.Flyout>
</Button>
<!-- Flyout declared inline on a FrameworkElement -->
<TextBlock>
<FlyoutBase.AttachedFlyout>
<Flyout>
<!-- Flyout content -->
</Flyout>
</FlyoutBase.AttachedFlyout>
</TextBlock>
<!-- Shared resource flyouts -->
<!-- A shared Flyout resource -->
<Page.Resources>
<Flyout x:Key="SharedFlyoutResource">
<!-- Flyout content -->
</Flyout>
</Page.Resources>
<!-- A shared Flyout resource assigned to a Button -->
<Button Flyout="{StaticResource SharedFlyoutResource}"/>
<!-- A shared Flyout resource assigned to a FrameworkElement -->
<TextBlock FlyoutBase.AttachedFlyout="{StaticResource SharedFlyoutResource}"/>
Placing a Flyout
Note
Windows Store apps only. By default, a Flyout is shown above the element it’s attached to. You can change the flyout’s preferred placement by setting the Placement property to a FlyoutPlacementMode value of Top, Bottom, Left, or Right. The flyout is shown using the preferred placement if there's space for it on the screen. If there isn’t enough space, like when the element is near the edge of the screen, the flyout is placed using this fallback order:
Placement | Fall back order |
---|---|
Top | Top > Bottom > Left > Right |
Bottom | Bottom > Top > Left > Right |
Left | Left > Right > Top > Bottom |
Right | Right > Left > Top > Bottom |
In the image flyout example shown previously, the flyout's Placement property is set to Right, as shown here.
<Flyout x:Key="ImagePreviewFlyout" Placement="Right">
...
</Flyout>
Note
For Windows Phone Store apps, a Flyout is shown at the top of the screen by default. You can change the Placement property to FlyoutPlacementMode.Full to make the flyout cover the full screen. The Top, Bottom, Left, and Right values don't have any effect in Windows Phone apps.
Styling a Flyout
The body of a Flyout is always shown using either the light or high-contrast theme. You can't style a Flyout control directly.
You can modify some aspects of the flyout's appearance, such as background, border, size constraints, and ScrollViewer settings, by styling the flyout's FlyoutPresenter.
In the image flyout example shown previously, the flyout's appearance is modified by setting the FlyoutPresenterStyle, as shown here.
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="ScrollViewer.ZoomMode" Value="Enabled"/>
<Setter Property="Background" Value="GhostWhite"/>
<Setter Property="BorderThickness" Value="5"/>
<Setter Property="MinHeight" Value="300"/>
<Setter Property="MinWidth" Value="300"/>
</Style>
</Flyout.FlyoutPresenterStyle>
Samples
To learn more about the Flyout control, download the XAML Flyout and MenuFlyout sample.
Summary and next steps
You learned how to use a Flyout control to show temporary, contextual UI to a user.
Learn how to use a MenuFlyout control to show a contextual menu of items to users in the Quickstart: Adding a MenuFlyout tutorial.