在纯XAML中使用Button关闭ComboBox DropDown

时间:2018-03-31 10:23:48

标签: xaml

我正在尝试使用纯粹的XAML关闭带有button.click事件的ComboBox DropDown列表。

我使用了默认的ComboBox模板,我所做的唯一重大更改是在Popup上,在 ItemsPresenter 下我插入了一个这样的按钮:

<Button Grid.Row="1" Width="200" Margin="5" Content="Close ComboBox DropDown">
   <Button.Triggers>
      <EventTrigger RoutedEvent="Button.Click">
        <BeginStoryboard>
          <Storyboard>
            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.Target="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}" Storyboard.TargetProperty="IsDropDownOpen">
              <DiscreteObjectKeyFrame KeyTime="0" Value="False" />
           </ObjectAnimationUsingKeyFrames>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

当我运行它时,我感到讨厌:无法为IsDropDownOpen&#39;设置动画。 “System.Windows.Controls.ComboBox”上的属性&#39;使用&#39; System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames&#39;

请帮忙。

以下是ComboBox样式的顶部:

  <Style TargetType="{x:Type ComboBox}">
   <Setter Property="FocusVisualStyle">
    <Setter.Value>
     <Style>
      <Setter Property="Control.Template">
       <Setter.Value>
        <ControlTemplate>
         <Rectangle Margin="2" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2" />
        </ControlTemplate>
       </Setter.Value>
      </Setter>
     </Style>
    </Setter.Value>
   </Setter>
   <Setter Property="Background">
    <Setter.Value>
     <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
      <GradientStop Color="#FFF0F0F0" Offset="0" />
      <GradientStop Color="#FFE5E5E5" Offset="1" />
     </LinearGradientBrush>
    </Setter.Value>
   </Setter>
   <Setter Property="BorderBrush" Value="#FFACACAC" />
   <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
   <Setter Property="BorderThickness" Value="1" />
   <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
   <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
   <Setter Property="Padding" Value="6,3,5,3" />
   <Setter Property="ScrollViewer.CanContentScroll" Value="True" />
   <Setter Property="ScrollViewer.PanningMode" Value="Both" />
   <Setter Property="Stylus.IsFlicksEnabled" Value="False" />
   <Setter Property="Template">
    <Setter.Value>
     <ControlTemplate TargetType="{x:Type ComboBox}">
      <Grid x:Name="templateRoot" SnapsToDevicePixels="True">
       <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0" />
       </Grid.ColumnDefinitions>
       <Popup x:Name="PART_Popup" AllowsTransparency="True" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
        <Themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}">
         <Border x:Name="DropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
          <ScrollViewer x:Name="DropDownScrollViewer">
           <Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
            <Grid.RowDefinitions>
             <RowDefinition Height="*" />
             <RowDefinition Height="33" />
            </Grid.RowDefinitions>
            <Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
             <Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=DropDownBorder}" Height="{Binding ActualHeight, ElementName=DropDownBorder}" Width="{Binding ActualWidth, ElementName=DropDownBorder}" />
            </Canvas>
            <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
            <Button Grid.Row="1" Width="200" Margin="5" Content="Close ComboBox DropDown">
             <Button.Triggers>
              <EventTrigger RoutedEvent="Button.Click">
               <BeginStoryboard>
                <Storyboard>
                 <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.Target="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}" Storyboard.TargetProperty="IsDropDownOpen">
                  <DiscreteObjectKeyFrame KeyTime="0" Value="False" />
                 </ObjectAnimationUsingKeyFrames>
                </Storyboard>
               </BeginStoryboard>
              </EventTrigger>
             </Button.Triggers>
            </Button>
           </Grid>
          </ScrollViewer>
         </Border>
        </Themes:SystemDropShadowChrome>
       </Popup>

Hello Gys,

我发现这似乎有效,除了使用按钮克隆DropDown后,ComboBox无法再次打开。

有什么想法吗?

到目前为止,这是解决方案:

<Button.Triggers>
   <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
          <Storyboard>
            <BooleanAnimationUsingKeyFrames Storyboard.Target="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}" Storyboard.TargetProperty="(ComboBox.IsDropDownOpen)">
               <DiscreteBooleanKeyFrame KeyTime="0" Value="False" />
            </BooleanAnimationUsingKeyFrames>          
          </Storyboard>
       </BeginStoryboard>
    </EventTrigger>
</Button.Triggers>

1 个答案:

答案 0 :(得分:0)

我想出了如何做到这一点,最后解决方案比我最初的解决方案简单得多。问题是我想在ComboBox弹出窗口中放置一个小关闭按钮以手动关闭弹出窗口。我必须承认我从谷歌搜索得到的一些答案导致了我的困惑。

诀窍在于了解CombBox的工作原理。有三个主要的“开关”控制我们在ComboBox中看到的Popup的整个打开和关闭。

这一切都以一个ToggleButton开头,它有两个状态(布尔值):它是Open或Closed。换句话说,它是ON或OFF。 ToggleButton的ON或OFF绑定到ComboBox的IsDropDownOPen状态,也可以是YES或NO(On或OFF)。反过来ComboBox的ON或OFF进一步绑定到也为ON或OFF的Popup状态。这三个因为它和谐共处。将这些视为三个交通信号灯,它们以一种方式同步,当一个开启时,所有三个都必须为ON,反之亦然。

有了这样的理解,我想,如果我在Popup中放置另一个ToggleButton,我可以将其用作打开/关闭按钮,它也被绑定到ComboBox的IsDropDownOPen状态为YES或NO,那么我可以实现我的目标通缉。究竟这就是发生的事情。

因此,当我单击ToggleButton以启动ComboBox的打开过程时:

  

IsChecked 变为YES

     

这使CombBox的 IsDropDownOpen 更改为YES

     

这使Popup' IsOpen 变为YES

     

这也是第二个ToggleButton的 IsChecked 状态   变成是

当我通过单击弹出窗口上的ToggleButton(我的关闭按钮)来反转该过程时,其他所有内容都会更改其状态(变为NO)并且弹出窗口关闭。

我做了正确的事还是我错过了什么?