我在一个资源字典中定义了一个名为"ConextPopup"的弹出窗口,如下所示:

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

该弹出窗口具有名为"ContextPopup_PreviewKeyDown"的PreviewKeyDown方法,该方法在资源字典代码隐藏文件中定义如下:

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

Csharp相关问答推荐

Rx.Net -当关闭序列被触发时如何聚合消息并发出中间输出?

更改对象的旋转方向

. NET在上一个操作完成之前,在此上下文实例上启动了第二个操作

我需要两个属性类吗

如何在C#中从正则表达式中匹配一些数字但排除一些常量(也是数字)

如何使用C#中的主构造函数功能使用多个构造函数?

WinForms在Linux上的JetBrains Rider中的应用

C#Null判断处理失败

HttpRequestMessage.SetPolicyExecutionContext不会将上下文传递给策略

将操作从编辑页重定向到带参数的索引页

无法使用[FromForm]发送带有图像和JSON的多部分请求

当try 测试具有协变返回类型的抽象属性时,类似功能引发System.ArgumentException

JsonPath在Newtonsoft.Json';S实现中的赋值

将J数组转换为列表,只保留一个嵌套的JToken

忽略Visual Studio代码中的StyleCop规则

Maui:更改代码中的绑定字符串不会更新UI,除非重新生成字符串(MVVM)

通过mini kube中的远程调试Pod与从emoteProcessPickerScript中解析错误输出的代码错误进行比较

如何对列表<;列表>;使用集合表达式?

同时通过多个IEumable<;T&>枚举

带有类约束的C#泛型