WPF:组合框中的TreeView

WPF:组合框中的TreeView,wpf,combobox,treeview,Wpf,Combobox,Treeview,我试图在WPF中的ComboBox中放置一个TreeView,这样当删除ComboBox时,用户将得到一个层次列表,而不是一个平面列表,并且他们选择的任何节点都将成为ComboBox的选定值 我一直在寻找如何做到这一点,但我能找到的最好的方法只是一些潜在的解决方案,因为我对WPF陌生得离谱,所以我无法工作 我对WPF和数据绑定有足够的了解,我可以将数据放入treeview,甚至可以将treeview放在组合框中,但是我所能完成的工作完全不正常。我附上了一张截图来说明我的意思。在屏幕截图中,组合框

我试图在WPF中的ComboBox中放置一个TreeView,这样当删除ComboBox时,用户将得到一个层次列表,而不是一个平面列表,并且他们选择的任何节点都将成为ComboBox的选定值

我一直在寻找如何做到这一点,但我能找到的最好的方法只是一些潜在的解决方案,因为我对WPF陌生得离谱,所以我无法工作

我对WPF和数据绑定有足够的了解,我可以将数据放入treeview,甚至可以将treeview放在组合框中,但是我所能完成的工作完全不正常。我附上了一张截图来说明我的意思。在屏幕截图中,组合框是“打开”的,因此底部的树状视图是我可以选择节点的地方,树状视图“在顶部”被绘制在组合框的顶部,我希望显示树中所选节点的文本/值

基本上,我不知道该怎么做,就是如何让treeview当前选择的节点将其值返回到combobox,combobox随后将其用作其选择值

以下是我当前使用的xaml代码:

        <ComboBox Grid.Row="0" Grid.Column="1"  VerticalAlignment="Top">
        <ComboBoxItem>
            <TreeView ItemsSource="{Binding Children}" x:Name="TheTree">
                <TreeView.Resources>
                    <HierarchicalDataTemplate DataType="{x:Type Core:LookupGroupItem}" ItemsSource="{Binding Children}">
                        <TextBlock Text="{Binding Path=Display}"/>                            
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
        </ComboBoxItem>
    </ComboBox>


屏幕截图:

您可以使用树视图上的事件处理程序在组合框上设置SelectedItem

为此,您需要设置树状视图的标记属性,如下所示:

<TreeView Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}"  MouseDoubleClick="treeview_MouseDoubleClick" ItemsSource="{Binding Children}" x:Name="TheTree">

您还需要覆盖选择组合框项目的方式,否则一旦单击它,整个树视图就会被选中。

这个问题实际上与

所以你可能会觉得很有帮助。这是一个包含复选框的组合框,但是您可以了解如何将框中的文本与树中的弹出内容解耦

它还演示了
IsSelected
属性应该位于模型实体上,然后通过模型将其绑定回复选框
Text
属性。换句话说,您在组合框中显示的内容可能与内容完全无关。。。嗯,也许不完全是这样,但在我的应用程序中,当用户在组合框中选择多个复选框时,我可以在顶部文本框中显示逗号分隔,或者我可以显示“已选择的多个选项”,或者其他

HTH=)

我也有同样的问题

在组合框中实现treeview行为的最简单方法是创建一个文本框并将其样式化为组合框。在其旁边添加一个图像。诀窍是将treeview置于弹出控件中。然后,当用户单击文本框或您选择的下拉图像时,弹出窗口将直接显示在文本框下方

然后,当选择treeview项目时,关闭弹出窗口并将所选项目的文本放入文本框中

下面是一个未序列化的示例:

XAML:


下面是背后的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ComboBoxTreeView
{
   /// <summary>
   /// Interaction logic for MainWindow.xaml
   /// </summary>
   public partial class MainWindow : Window
   {
      public MainWindow()
      {
         InitializeComponent();
      }

      private void Window_MouseEnter(object sender, MouseEventArgs e)
      {

      }

      private void Tree1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
      {
         var trv = sender as TreeView;
         var trvItem = trv.SelectedItem as TreeViewItem;
         if (trvItem.Items.Count != 0) return;
         header.Text = trvItem.Header.ToString();
         PopupTest.IsOpen = false;
      }

      private void Tree1_Initialized(object sender, EventArgs e)
      {
         var trv = sender as TreeView;
         var trvItem = new TreeViewItem() { Header="Initialized item"};
         var trvItemSel = trv.Items[1] as TreeViewItem;
         trvItemSel.Items.Add(trvItem);
      }

      private void header_PreviewMouseDown(object sender, MouseButtonEventArgs e)
      {
         PopupTest.Placement = System.Windows.Controls.Primitives.PlacementMode.RelativePoint;
         PopupTest.VerticalOffset = header.Height;
         PopupTest.StaysOpen = true;
         PopupTest.Height = Tree1.Height;
         PopupTest.Width = header.Width;
         PopupTest.IsOpen = true;
      }
   }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
命名空间ComboxTreeView
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
私有无效窗口\u鼠标指针(对象发送器,鼠标指针)
{
}
私有无效树1\u SelectedItemChanged(对象发送方,RoutedPropertyChangedEventArgs e)
{
var trv=作为树视图的发送方;
var trvItem=trv.SelectedItem作为TreeViewItem;
如果(trvItem.Items.Count!=0)返回;
header.Text=trvItem.header.ToString();
PopupTest.IsOpen=false;
}
私有无效树1_已初始化(对象发送方,事件参数e)
{
var trv=作为树视图的发送方;
var trvItem=new TreeViewItem(){Header=“Initialized item”};
var trvItemSel=trv.Items[1]作为树项目;
trvItemSel.Items.Add(trvItem);
}
private void标头_PreviewMouseDown(对象发送器,鼠标按钮Ventargs e)
{
PopupTest.Placement=System.Windows.Controls.Primitives.PlacementMode.RelativePoint;
PopupTest.VerticalOffset=页眉高度;
PopupTest.StaysOpen=true;
PopupTest.Height=Tree1.Height;
PopupTest.Width=标题.Width;
PopupTest.IsOpen=true;
}
}
}

我认为您可以将每个树元素添加到组合1by1中

在每个treeviewitem展开事件中,将其子项追加到combobox中

但是,将可展开项的高度设置为一行中的外观,例如高度=18d

// == Append Item into combobox =================
TreeViewItem root = new TreeViewItem();
root.Header = "item 1";
TreeViewItem t1 = new TreeViewItem();
t1.Header = "Expanding...";
root.Items.Add(t1);
// ==============================================

// == root expandind event ==============================
root.Height = 18.00d;
TreeViewItem[] items = GetRootChildren(root.Tag);
foreach(TreeViewItem item in items)
{
    combox1.Items.Add(item);
}
// ======================================================

对于那些仍然需要此控件的用户,我已经实现了我的WPF版本。它只适用于视图模型,并要求这些视图模型实现一个特殊的接口,但除此之外,使用起来并不困难

在WPF中,它如下所示:


您可以从这里下载源代码和示例应用程序:

这是一个古老的主题,但对某些人可能有用

我试着用一个组合框做一些类似的事情,我试着用popup来代替它,它开始工作了。 要把它变成一个好的功能,它需要很多调整

<Expander Header="TestCS">
    <Popup IsOpen="{Binding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Expander}}}">
        <TreeView ItemsSource="{Binding CSTree.CSChildren}">
            <TreeView.Resources>
                <HierarchicalDataTemplate ItemsSource="{Binding CSChildren}" DataType="{x:Type ViewModel:ObservableCS}">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="16" Text="{Binding CSName}"></TextBlock>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
    </Popup>
</Expander>


你有两个问题
// == Append Item into combobox =================
TreeViewItem root = new TreeViewItem();
root.Header = "item 1";
TreeViewItem t1 = new TreeViewItem();
t1.Header = "Expanding...";
root.Items.Add(t1);
// ==============================================

// == root expandind event ==============================
root.Height = 18.00d;
TreeViewItem[] items = GetRootChildren(root.Tag);
foreach(TreeViewItem item in items)
{
    combox1.Items.Add(item);
}
// ======================================================
<Expander Header="TestCS">
    <Popup IsOpen="{Binding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Expander}}}">
        <TreeView ItemsSource="{Binding CSTree.CSChildren}">
            <TreeView.Resources>
                <HierarchicalDataTemplate ItemsSource="{Binding CSChildren}" DataType="{x:Type ViewModel:ObservableCS}">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="16" Text="{Binding CSName}"></TextBlock>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
    </Popup>
</Expander>