Rahul Sonone
Rahul Sonone

Reputation: 2745

Prevent Flyout opening dynamically

I am using AppBarButton and based on one condition I want to execute either direct command on AppBarButton click or display flyout for additional input, the issue is if flyout is there in the appbar button it will always open when button clicks.

Is there any way I can decide where to allow Flyout to open or not.

 <AppBarButton x:Uid="Accept" Label="Accept"
                      ToolTipService.ToolTip="{Binding Label, RelativeSource={RelativeSource Mode=Self}}"
                      Icon="Accept"
                      Command="{Binding AcceptAppBarCommand}" 
                      behaviors:AppBarButtonBehavior.AllowFocusOnInteraction="True">
            <AppBarButton.Flyout>
                <Flyout Placement="Bottom" >
                    <StackPanel Width="200">
                        <PasswordBox Header="Enter password:"
                                     Password="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                        <Button Margin="0 5 0 0" Content="Accept"
                                Command="{Binding AcceptCommand}">
                        </Button>
                    </StackPanel>
                </Flyout>
            </AppBarButton.Flyout>
        </AppBarButton>

Upvotes: 1

Views: 607

Answers (2)

Romasz
Romasz

Reputation: 29792

Generally if a control derives from a Button class, the flyout is being showed automatically:

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 generally happens if you add your flyout to Flyout property. If you don't won't such behavior, then attach flyout by FlyoutBase or add it to resources:

<AppBarButton x:Uid="Accept" Label="Accept"
              ToolTipService.ToolTip="{Binding Label, RelativeSource={RelativeSource Mode=Self}}"
              Icon="Accept"
              Command="{Binding AcceptAppBarCommand}"
              Click="AppBarButton_Click"> <!-- for sample -->
    <FlyoutBase.AttachedFlyout>
        <Flyout Placement="Bottom" x:Key="myFlyout" >
            <StackPanel Width="200">
                <PasswordBox Header="Enter password:"
                             Password="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                <Button Margin="0 5 0 0" Content="Accept"
                        Command="{Binding AcceptCommand}">
                </Button>
            </StackPanel>
        </Flyout>
    </FlyoutBase.AttachedFlyout>
</AppBarButton>

and show when needed:

private void AppBarButton_Click(object sender, RoutedEventArgs e)
{
    // in command, click or anywhere else (in that change move to suitable resources)
    FlyoutBase.ShowAttachedFlyout(sender as FrameworkElement);
}

If you are looking more information about building a helper class/methods to make it more MVVM friendly take a look at Macrominevra blog post, Depechie's post and Shawn Kendrot's.

Upvotes: 1

Rahul Sonone
Rahul Sonone

Reputation: 2745

I found one work around, through style.

Create styles in resources

<Page.Resources>

    <Style TargetType="FlyoutPresenter" x:Key="_hiddenFlyoutStyle">
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="BorderBrush" Value="Transparent" />
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="Padding" Value="0" />
    </Style>

    <Style TargetType="Border" x:Key="_flyoutBorderStyle">
        <Setter Property="Background" Value="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}"/>
        <Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundChromeHighBrush}"/>
        <Setter Property="BorderThickness" Value="{ThemeResource FlyoutBorderThemeThickness}"/>
        <Setter Property="Padding" Value="{ThemeResource FlyoutContentThemePadding}"/>
        <Setter Property="MinWidth" Value="{ThemeResource FlyoutThemeMinWidth}"/>
        <Setter Property="MaxWidth" Value="{ThemeResource FlyoutThemeMaxWidth}"/>
        <Setter Property="MinHeight" Value="{ThemeResource FlyoutThemeMinHeight}"/>
        <Setter Property="MaxHeight" Value="{ThemeResource FlyoutThemeMaxHeight}"/>
        <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Auto"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    </Style>
</Page.Resources>

Apply style to flyout and border.

<AppBarButton x:Uid="Accept" Label="Accept"
                      ToolTipService.ToolTip="{Binding Label, RelativeSource={RelativeSource Mode=Self}}"
                      Icon="Accept"
                      Command="{Binding AcceptAppBarCommand}" 
                      behaviors:AppBarButtonBehavior.AllowFocusOnInteraction="True">
            <AppBarButton.Flyout>
                <Flyout Placement="Bottom" FlyoutPresenterStyle="{StaticResource _hiddenFlyoutStyle}">
                    <Border Visibility="{Binding DisplayFlyout, Converter={StaticResource BooleanToVisibilityConverter}}" 
                            Style="{StaticResource _flyoutBorderStyle}">
                        <StackPanel Width="200">
                            <PasswordBox Header="Enter password:"
                                     Password="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                            <Button Margin="0 5 0 0" Content="Accept"
                                Command="{Binding AcceptCommand}">
                            </Button>
                        </StackPanel>
                    </Border>
                </Flyout>
            </AppBarButton.Flyout>
        </AppBarButton>

DisplayFlyout is a bool property in viewmodel to decide when to Display flyout.

Upvotes: 0

Related Questions