Search code examples
windows-runtimewinrt-xamlwinrt-asyncflyoutwinrt-component

Is it possible to temporarily postpane displaying an AppBarButton's affiliated Flyout?


I've got a Flyout embedded within an AppBarButton like so:

<AppBarButton x:Name="appbarbtnOpenPhotosets" Icon="OpenFile" Label="Open Existing Photoset[s]" AutomationProperties.Name="Open File" Tapped="appbarbtnOpenPhotosets_Tapped" >
    <Button.Flyout>
    . . .
    </Button.Flyout>
</AppBarButton>

I want to, under certain circumstances, first present the user with an opportunity to rename a file prior to seeing the Flyout. I tried seeing if that would work like this:

async private void appbarbtnOpenPhotosets_Tapped(object sender, TappedRoutedEventArgs args)
{
    // Want to conditionally postpone the operation
    bool myBucketsGotAHoleInIt = PhotraxUtils.GetLocalSetting(CAINT_BUY_NO_BEER);
    if (myBucketsGotAHoleInIt)
    {
        MessageDialog dlgDone = new MessageDialog("Can you see me now?");
        await dlgDone.ShowAsync();
        args.Handled = false; // <= adding this made no difference
    }
}

This works, in that I see the "Can you see me now?" dialog, but that prevents the Flyout from flying out. A Flyout that doesn't fly out is no more useful than a flying squirrel or fish that doesn't motate through the air.

So how can I temporarily suppress my flyout but then call it forth? The Flyout does not have an Open() method...Is there some other way to invoke it?


Solution

  • Flyouts attached to Buttons open automatically when you click the control. If you don't want it to open automatically, you need to attach it to another control.

    Example taken from official documentation:

    <!-- Flyout declared inline on a FrameworkElement -->
    <TextBlock>
        <FlyoutBase.AttachedFlyout>
            <Flyout>
            <!-- Flyout content -->
            </Flyout>
        </FlyoutBase.AttachedFlyout>
    </TextBlock>
    

    Then you can show the Flyout whenever you want, calling FlayoutBase.ShowAttachedFlyout() and passing the FrameworkElement casted value of your control.

    FlyoutBase.ShowAttachedFlyout(frameworkElement);
    

    So, in your case:

    async private void appbarbtnOpenPhotosets_Tapped(object sender, TappedRoutedEventArgs args)
    {
        // Want to conditionally postpone the operation
        bool myBucketsGotAHoleInIt = PhotraxUtils.GetLocalSetting(CAINT_BUY_NO_BEER);
        if (myBucketsGotAHoleInIt)
        {
            MessageDialog dlgDone = new MessageDialog("Can you see me now?");
            await dlgDone.ShowAsync();
            // New code
            FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
        }
    }
    

    If you can't change the control, you should able to use the code I posted with Buttoninstead of TextBlock. I'm not sure about this, but you can try.