1

我刚刚注意到 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 不是列表。根据需要显示数据。只有鼠标选择失败!

替代文字 http://img682.imageshack.us/img682/3702/bildy.png

4

1 回答 1

3

TreeViews 的工作方式不同。HierarchicalDataTemplate 中的 ItemTreeViewItems,您在 HierarchicalDataTemplate 中指定的任何控件都将用作其 Header。所以,基本上你是在指定 TreeView 中的 Item 是 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;
        }
    }
}
于 2010-04-12T23:02:36.397 回答