奇怪的行为WPF TreeView ItemContainerStyle和ItemTemplate

时间:2010-04-12 14:36:11

标签: wpf treeview itemtemplate itemcontainerstyle

我刚刚注意到WPF的TreeView的一些奇怪的行为。我添加了ItemContainerStyle以绑定到我的ViewModel的“IsSelected”和ItemsTemplated以自定义显示我的数据。但现在用户无法再更改所选节点。出于测试目的,我使用ListView和Expander创建了一个类似的UI。此版本作为例外。有关TreeView失败的任何提示吗?

 <TreeView ItemsSource="{Binding ElementName=frame, Path=list}">
        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}" >
                <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
            </Style>
        </TreeView.ItemContainerStyle>
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate>
                <TreeViewItem Header="{Binding}">
                    <TextBlock Text="{Binding Path= Item.SomeData}"/>
                </TreeViewItem>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

编辑:我的数据不是层次结构。我只想在显示列表时获得“折叠”功能。 Item.SomeData不是列表。根据需要显示数据。只有鼠标选择失败!

alt text http://img682.imageshack.us/img682/3702/bildy.png

1 个答案:

答案 0 :(得分:3)

TreeViews的工作方式不同。 HierarchicalDataTemplate 中的Items是 TreeViewItems,您在HierarchicalDataTemplate中指定的任何控件都将用作其Header。所以,基本上你指定TreeView中的Items是TreeViewItems,TreeViewItems作为标题!相反,试试这个:

 <HierarchicalDataTemplate ItemsSource="{Binding Items}"> 
      <Label Content="{Binding}"/>
      <HierarchicalDataTemplate.ItemTemplate>
         <DataTemplate> 
             <TextBlock Text="{Binding Path= Item.SomeData}"/> 
         </DataTemplate>
      </HierarchicalDataTemplate.ItemTemplate> 
  </HierarchicalDataTemplate>
编辑:我无法重现产生你想要绑定的属性的DataSource,所以我写了一些我自己的简单代码,展示了它是如何工作的。希望您能够根据自己的需求进行调整:

<TreeView ItemsSource="{Binding}" Name="Tree">
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}" >
                    <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
                </Style>
            </TreeView.ItemContainerStyle>
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Items}">
                    <Label Content="{Binding Name}"/>
                    <HierarchicalDataTemplate.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path= SomeData}"/>
                        </DataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;

namespace TreeViewSpike
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            List = new List<ItemList>
                       {
                           new ItemList
                               {
                                   Name = "MyList",
                                   Items = new List<Item> {new Item("1"),
                                                           new Item("2")}
                               },
                           new ItemList
                               {
                                   Name = "MySecondList",
                                   Items = new List<Item> {new Item("3"),
                                                           new Item("4")}
                               }
                       };
            Tree.DataContext = List;
            List[1].IsSelected = true;
        }

        public List<ItemList> List { get; set; }
    }

    public class ItemList: INotifyPropertyChanged
    {
        public string Name{ get; set;}
        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                _isSelected = value;
                if (PropertyChanged != null)
                    PropertyChanged(this,
                        new PropertyChangedEventArgs("IsSelected"));
                if(_isSelected)
                   MessageBox.Show(Name + " selected");
            }
        }

        public List<Item> Items { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class Item
    {
        public string SomeData { get; set; }
        public Item(string data)
        {
            SomeData = data;
        }
    }
}