Search code examples
c#xamlwinui-3resourcedictionary

With C# and WinUI3, how do you create a reusable flyout in XAML and create multiple instances of it in several code-behinds?


I have a Flyout I want to reuse across several classes.

            <CommandBarFlyout x:Name="BasicFlyout"
                              AlwaysExpanded="True"
                              x:Key="ImageContextMenu">
                
                <CommandBarFlyout.SecondaryCommands>

                    <AppBarButton x:Name="1"
                    Label="A"/>
                    <AppBarButton x:Name="2"
                    Label="B"/>
                    <AppBarButton x:Name="3"
                    Label="C"/>
                    <AppBarButton x:Name="4"
                    Label="D"/>
                    
                </CommandBarFlyout.SecondaryCommands>
                
            </CommandBarFlyout>

I need to attach a unique combination of the buttons for up to 120 images and each image has an associated state class that contains boolean flags for whether each button should be visible or not as well as callbacks for each button which will be set in the code-behind.

Ideally, it would look something like this, though the syntax is off.

CommandBarFlyout flyout = new Resources["ImageContextMenu"] as CommandBarFlyout;
// Set visibility and callbacks
FlyoutBase.SetAttachedFlyout(image, flyout);

The problem is I am not sure how to declare this in XAML. It looks like the code has to be added to the resources of the entire project, but I am not sure how to do that. The resource dictionary will not allow me to use CommandBarFlyout as the root element.


Solution

  • As you said, it seems that the resource dictionary will not allow us to use CommandBarFlyout as the root element.

    I suggest you could try to add CommandBarFlyout in the StackPanel.Resources. And then you could try to use {StaticResource} markup extension

    like:

    <Button x:Name="myButton" Click="myButton_Click" FlyoutBase.AttachedFlyout="{StaticResource ImageContextMenu}">Click Me</Button>
    

    Or use {x:Bind} markup extension

    Like:

    <Button x:Name="myButton" Click="myButton_Click" FlyoutBase.AttachedFlyout="{x:Bind BasicFlyout}">Click Me</Button>