防止 Flyout 动态打开
Posted
技术标签:
【中文标题】防止 Flyout 动态打开【英文标题】:Prevent Flyout opening dynamically 【发布时间】: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>
【问题讨论】:
【参考方案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 post、Depechie's post 和 Shawn 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 属性,用于决定何时显示弹出窗口。
【讨论】:
marcominerva.wordpress.com/2015/01/15/…,这个也不错,附属性的帮助下。以上是关于防止 Flyout 动态打开的主要内容,如果未能解决你的问题,请参考以下文章
从 UWP 中的自定义 ToolTip 和自定义 Flyout 类取消订阅事件