0

I am trying to close a ComboBox DropDown list with a button.click event using purely XAML.

I have used a default ComboBox Template and the only major change I have made is on the Popup where under ItemsPresenter I have inserted a button like this:

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

When I run it I get the nasty: Cannot animate the 'IsDropDownOpen' property on a 'System.Windows.Controls.ComboBox' using a 'System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames'.

Please help.

Here is the top section of ComboBox Style:

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

I found this which seems to work except that after clossing the DropDown using the button, the ComboBox cannot open again.

Any ideas?

Here is the solution so far:

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

0

I figured out how to do it and in the end the solution was much simpler than I initially was going about it. The issue is that I wanted to place a little close button inside the ComboBox Popup to close the Popup manually. I must admit some of the answers I got from googling contributed to my confusion.

The trick lies in understanding how exactly a CombBox works. There are three main “switches” that control the whole opening and closing of the Popup that we see in a ComboBox.

It all begins with a ToggleButton which has two states (Boolean): It is either Open or Closed. In Other words it is either ON or OFF. The ToggleButton’s ON or OFF is bound to the ComboBox’s IsDropDownOPen states of also being either YES or NO (On or OFF). In turn The ComboBox’s ON or OFF is further bound to the Popup states of also ON or OFF. These three as it were work in harmony. Consider these as being three Traffic Lights which are synchronized in such a way that when one is ON all the three must be ON and vice versa.

With this understanding, I thought to myself that if I place another ToggleButton inside the Popup that I can use as a Open/Close button which is also bound to the ComboBox’s IsDropDownOPen states of YES or NO, I could then achieve what I wanted. Exactly this is what happened.

Hence when I click the ToggleButton to start the opening process of the ComboBox:

Its IsChecked becomes YES

Which makes the CombBox’s IsDropDownOpen to change to YES

Which makes the Popup’ IsOpen to become YES

Which makes the second ToggleButton’s IsChecked state to also become YES

When I reverse the process by clicking the ToggleButton placed on the Popup (my Close button) everything else changes their state (become NO) and the Popup closes.

Did I do the right thing or I am missing something here?

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.