ComboBox - TreeView,项目选择关闭弹出窗口?

时间:2011-05-20 17:29:56

标签: wpf xaml

我已设法使用selected item behavior创建一个带有treeview的ComboBox作为其itempresenter  这里。

<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 个答案:

答案 0 :(得分: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;
}

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

答案 1 :(得分:0)

我在xaml ala和事件触发器中做到了这一点。如果有人对此有任何优化,那么无论如何,请建议离开,我对此非常环保。

<强>更新 ...这部分有效,除非现在在您选择树中的项目后,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>
    ...

答案 2 :(得分: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));
    }