It appears that adding CharmFlyouts to apps like those generated with the Grid App template is difficult. The problem comes from the fact that there is no MainPage.xaml. Placing the CharmFlyout in each page, like GroupedItemsPage
, GroupDetailPage
, and ItemDetailPage
is fraught with problems as Martin Bennedik comments. Martin suggests placing the code in the LayoutAwarePage
, and the UI in a UserControl
. This makes a fair amount of sense and is worth pursuing.
Posts in this series:
In thinking about the problem, I wondered if there might be a different solution. Again, the root of the problem in Grid Apps is that there is no MainPage
that is always visible (in which we can embed our CharmFlyouts). It turns out, though, there is another user interface element that is always visible that can suit our purposes. Grid Apps have a Frame. This can be seen here:
App.xaml.cs
var rootFrame = new Frame();
Our goal is to embed our CharmFlyouts into this frame. It will take a few steps to get there, but I think the end result is worth it. Let’s set the stage by creating a Metro Grid App and adding the CharmFlyout library to it:
- Install the NuGet Package Manager if you have not already.
- Create your Metro Grid application in Visual Studio.
- Select Manage NuGet Packages from the Project menu.
- Click Online. Search for CharmFlyout. Click Install.
Create a UserControl
to host your flyouts and call it MyCharmFlyouts
. Here is what I created:
<UserControl
x:Class="CharmDemoGridApp.MyCharmFlyouts"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CharmDemoGridApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:cfo="using:CharmFlyoutLibrary"
mc:Ignorable="d">
<Grid>
<cfo:CharmFlyout
x:Name="cfoAbout"
Heading="My About"
HeadingBackgroundBrush="#FF4E0000">
<StackPanel>
<TextBlock
FontSize="16">CharmFlyout by John Michael Hauck</TextBlock>
<TextBlock
FontSize="16">For support:</TextBlock>
<HyperlinkButton
Click="OnMailTo">support@bing.com</HyperlinkButton>
</StackPanel>
</cfo:CharmFlyout>
<cfo:CharmFlyout
x:Name="cfoSettings"
Heading="My Settings"
HeadingBackgroundBrush="#FF4E0000">
<StackPanel>
<TextBlock
FontSize="16">Setting A</TextBlock>
<CheckBox />
<TextBlock
FontSize="16">Setting B</TextBlock>
<CheckBox />
<TextBlock
FontSize="16">Setting C</TextBlock>
<CheckBox />
</StackPanel>
</cfo:CharmFlyout>
</Grid>
</UserControl>
MyCharmFlyouts.xaml.cs
using System;
using Windows.UI.ApplicationSettings;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace CharmDemoGridApp
{
public sealed partial class MyCharmFlyouts : UserControl
{
public MyCharmFlyouts()
{
this.InitializeComponent();
SettingsPane.GetForCurrentView().CommandsRequested += CommandsRequested;
}
private void CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
{
args.Request.ApplicationCommands.Add(new SettingsCommand
("a", "My About", (p) => { cfoAbout.IsOpen = true; }));
args.Request.ApplicationCommands.Add(new SettingsCommand
("s", "My Settings", (p) => { cfoSettings.IsOpen = true; }));
}
private async void OnMailTo(object sender, RoutedEventArgs args)
{
var hyperlinkButton = sender as HyperlinkButton;
if (hyperlinkButton != null)
{
var uri = new Uri("mailto:" + hyperlinkButton.Content);
await Windows.System.Launcher.LaunchUriAsync(uri);
}
}
}
}
Modify App.xaml.cs to use a frame that supports additional content, and add your new flyout user control to it. One such handy frame is now included in the CharmFlyoutLibrary
, called CharmFrame
.
App.xaml.cs
var rootFrame = new CharmFrame { CharmContent = new MyCharmFlyouts() };
That’s it!