WPF弹出-当按下ESC键时如何关闭WPF弹出

  • 本文关键字:WPF 弹出 何关闭 ESC c# wpf popup
  • 更新时间 :
  • 英文 :


我有一个名为" ContextPopup"在ResourceDictionary中定义如下:

<ControlTemplate x:Key="UXIconComboBoxControlTemplate" TargetType="{x:Type controls:UXIconComboBox}" >
<ControlTemplate.Resources>
<converters:IconComboBoxDropdownHorizontalOffsetMultiConverter x:Key="ComboBoxDropdownHorizontalOffsetConverter"/>
</ControlTemplate.Resources>
<Grid 
x:Name="rootGrid"
Width="{TemplateBinding HitAreaWidth}" 
Height="{TemplateBinding HitAreaHeight}" 
Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<controls:ExtendedHitAreaButton 
Grid.Row="0"
x:Name="OpenPopupIconButton"
IsDefault="True"
Style="{StaticResource UXIconComboBoxButtonStyle}">
<controls:ExtendedHitAreaButton.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames 
Storyboard.TargetName="ContextPopup" 
Storyboard.TargetProperty="IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0.25" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</controls:ExtendedHitAreaButton.Triggers>
</controls:ExtendedHitAreaButton>
<Popup 
x:Name="ContextPopup"
Grid.Row="1" 
Placement="Bottom"
PlacementTarget="{Binding ElementName=OpenPopupIconButton}"
StaysOpen="False"
PreviewKeyDown="ContextPopup_PreviewKeyDown">
<Popup.HorizontalOffset>
<MultiBinding Converter="{StaticResource ComboBoxDropdownHorizontalOffsetConverter}">
<Binding ElementName="OpenPopupIconButton" Path="ActualWidth"/>
<Binding ElementName="PopupListBox" Path="ActualWidth"/>
</MultiBinding>
</Popup.HorizontalOffset>
<ListBox 
x:Name="PopupListBox" 
ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource TemplatedParent}}"
ItemTemplate="{Binding ItemTemplate, RelativeSource={RelativeSource TemplatedParent}}"
Loaded="PopupListBox_OnLoaded"
KeyboardNavigation.IsTabStop="True"
KeyboardNavigation.TabNavigation="Continue"
BorderThickness="0"/>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IconComboBoxSemanticColorType}" Value="Default"/>
<Condition Binding="{Binding Path=IsOpen, ElementName=ContextPopup}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="{DynamicResource BrushIconComboBox_Popup_Open_Background}" />
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>

弹出窗口有一个PreviewKeyDown方法叫做contextpopup_previewkeydown;在ResourceDictionary代码隐藏文件中定义,如下所示:

private void ContextPopup_PreviewKeyDown(object sender, KeyEventArgs e)
{
var popupControl = sender as Popup;
if (e.Key == Key.Escape)
{
popupControl.IsOpen = false;
}
}

当弹出窗口显示时,我按ESC键并验证调用了ContextPopup_PreviewKeyDown方法和popupControl。IsOpen属性设置为false,但是弹出窗口不关闭。

有谁能解释一下为什么这个弹出窗口没有关闭,该怎么办?

谢谢你的帮助。

只要Storyboard仍处于动画状态,就不能修改属性值。要么显式地停止Storyboard,要么应用另一个动画来修改值。

下面的例子使用VisualStateManager来触发动画

<ControlTemplate TargetType="{x:Type local:UXIconComboBox}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PopupStates">
<VisualState x:Name="PopupClosed">
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="PART_ContextPopup"
Storyboard.TargetProperty="IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0.25"
Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PopupOpen">
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="PART_ContextPopup"
Storyboard.TargetProperty="IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0.25"
Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Button x:Name="PART_OpenPopupIconButton" />
<Popup x:Name="PART_ContextPopup"
AllowsTransparency="True">
<TextBox Text="Hello World!" />
</Popup>
</Grid>
</Border>
</ControlTemplate>
public class UXIconComboBox : Control
{
private ButtonBase? PART_OpenPopupIconButton { get; set; }
private UIElement? PART_ContextPopup { get; set; }
static UXIconComboBox() 
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(UXIconComboBox), new FrameworkPropertyMetadata(typeof(UXIconComboBox)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.PART_OpenPopupIconButton = GetTemplateChild("PART_OpenPopupIconButton") as ButtonBase;
this.PART_OpenPopupIconButton.Click += OpenPopupIconButton_Click;
this.PART_ContextPopup = GetTemplateChild("PART_ContextPopup") as UIElement;
this.PART_ContextPopup.PreviewKeyDown += ContextPopup_PreviewKeyDown;
}
protected void ContextPopup_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
_ = VisualStateManager.GoToState(this, "PopupClosed", true);
}
}
private void OpenPopupIconButton_Click(object sender, System.Windows.RoutedEventArgs e) 
=> _ = VisualStateManager.GoToState(this, "PopupOpen", true);
}

最新更新