【问题标题】:Prevent Flyout opening dynamically防止 Flyout 动态打开
【发布时间】:2017-07-06 13:51:09
【问题描述】:

我正在使用 AppBarButton,并且基于一个条件,我想在 AppBarButton 单击时执行直接命令或显示浮出控件以进行额外输入,问题是如果浮出控件在 appbar 按钮中,则在单击按钮时它总是会打开。

我有什么方法可以决定在哪里打开 Flyout。

 <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>

【问题讨论】:

    标签: c# .net xaml windows-store-apps winrt-xaml


    【解决方案1】:

    通常,如果控件派生自 Button 类,则会自动显示浮出控件:

    当用户单击按钮时,附加到按钮的弹出按钮会自动打开。您无需处理任何事件即可打开弹出窗口。

    如果您将弹出窗口添加到 Flyout 属性,通常会发生这种情况。如果您不这样做,则通过 FlyoutBase 附加弹出窗口或将其添加到资源中:

    <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>
    

    并在需要时显示:

    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);
    }
    

    如果您正在寻找有关构建帮助器类/方法以使其对 MVVM 更友好的更多信息,请查看 at Macrominevra blog postDepechie's postShawn Kendrot's

    【讨论】:

    • 这个 Ans 可以工作,但它通过背后的代码解决问题,而不是通过 MVVM 模式。
    • @RahulSonone 甚至 MVVM 也需要一些代码。看看你的答案 - 你确定这是因为样式更改,我想它已经死了隐藏弹出(边框)的内容 - 然后它根本没有被显示。我已经编辑了答案并添加了一些链接,在 MVVM 的情况下您可能会发现它们很有用。
    • marcominerva.wordpress.com/2015/01/15/… 不错,我可以使用它,但目前风格对我来说还不错。
    【解决方案2】:

    我通过风格找到了一种解决方法。

    在资源中创建样式

    <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>
    

    将样式应用于浮出控件和边框。

    <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 是 viewmodel 中的 bool 属性,用于决定何时显示弹出窗口。

    【讨论】:

    猜你喜欢
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 2013-02-20
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    相关资源
    最近更新 更多