ComboBox - TreeView, close popup menu?

I managed to create a ComboBox with treeview as its itempresenter using the selected element behavior here.

<Popup x:Name="PART_Popup" AllowsTransparency="true" Focusable="false" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom"> <Microsoft_Windows_Themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{TemplateBinding ActualWidth}"> <Border x:Name="DropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"> <ScrollViewer> <TreeView x:Name="PART_TreeView" ItemsSource="{TemplateBinding ItemsSource}"> <Interactivity:Interaction.Behaviors> <ComboTreeView:BindableSelectedItemBehaviour SelectedItem="{Binding RelativeSource={RelativeSource AncestorType={x:Type ComboBox} }, Path=SelectedItem, Mode=TwoWay}" /> </Interactivity:Interaction.Behaviors> </TreeView> </ScrollViewer> </Border> </Microsoft_Windows_Themes:SystemDropShadowChrome> </Popup> 

Selecting an item in the tree correctly defines the selected list item. I am not sure how to close the popup. Every time I have to select and go beyond the control so that the popup disappears. Can this be done in XAML?

+4
source share
3 answers

In the behavior of BindableSelectedItemBehaviour I added the following logic. I think I will translate this to a new behavior, but it works.

  private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) { this.SelectedItem = e.NewValue; var treeView = (TreeView)sender; var control = (FrameworkElement)treeView.TemplatedParent; ComboBox combo; do { combo = control as ComboBox; if (combo != null) { break; } } while ((control = (FrameworkElement)control.TemplatedParent) != null); if (combo == null) { return; } Dispatcher.BeginInvoke(new Action(() => combo.IsDropDownOpen = false)); } 
0
source

I don't think this can be done in XAML, but it can be done in codebehind:

 void EnsureComboPopupClosed(ComboBox cb) { if (cb == null || cb.Template == null) return; Popup popup = cb.Template.FindName("PART_Popup", cb) as Popup; if (popup == null) return; popup.IsOpen = false; } 

You can use an event handler to call this function.

+3
source

I did this in the xaml ala Event Trigger. If anyone has any optimizations for this, then anyway, please suggest away, I'm pretty green with that.

UPDATE ... and this partially works, except that now the ComboBox does not open again after the selection and the item in the tree.

 ... xmlns:s="clr-namespace:System;assembly=mscorlib" ... ... <ControlTemplate.Resources> .... <Storyboard x:Key="ClosePopup" Duration="0:0:0" Storyboard.TargetName="PART_Popup" Storyboard.TargetProperty="IsOpen" > <ObjectAnimationUsingKeyFrames> <DiscreteObjectKeyFrame KeyTime="0:0:0"> <DiscreteObjectKeyFrame.Value> <s:Boolean>False</s:Boolean> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> ... </ControlTemplate.Resources> ... <TreeView x:Name="PART_TreeView" ... > ... <TreeView.Triggers> <EventTrigger RoutedEvent="TreeView.SelectedItemChanged"> <EventTrigger.Actions> ... <BeginStoryboard Storyboard="{StaticResource ClosePopup}"/> </EventTrigger.Actions> </EventTrigger> </TreeView.Triggers> ... </TreeView> ... 
0
source

All Articles