ComboBox - TreeView,选择项后如何关闭弹出窗口?

4

我已经成功创建了一个ComboBox,其ItemPresenter是使用选定项行为实现的TreeView。

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

在树形视图中选择一个项可以正确设置组合框的选定项。我不确定如何在选择后关闭弹出窗口。每次都必须选择并在控件外单击才能让弹出窗口消失。这可以在XAML中完成吗?

3个回答

3

我不认为可以在XAML中完成,但可以在代码后台中完成:

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

您可以使用事件处理程序调用此函数。

0

我是通过事件触发器在XAML中完成的。如果有人对此有任何优化建议,请不吝赐教,我在这方面还很新手。

更新 ... 这部分代码部分有效,但是在树中选择项目后,ComboBox现在将无法再次打开。

... 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
在行为 BindableSelectedItemBehaviour 中,我添加了以下逻辑。我认为我会将其移动到一个新的行为中,但这个可以工作。
    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));
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接