我已设法使用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中完成吗?
答案 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));
}