Странное поведение WPF TreeView ItemContainerStyle и ItemTemplate - PullRequest
1 голос
/ 12 апреля 2010

Я только что заметил странное поведение TreeFv в WPF. Я добавил и ItemContainerStyle для привязки к «IsSelected» моей ViewModel, и ItemsTemplated для пользовательского отображения моих данных. Но теперь пользователь не может изменить выбранный узел больше. Для тестирования я создал похожий пользовательский интерфейс, используя ListView и Expander. Эта версия работает как исключение. Любые советы, почему 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

1 Ответ

3 голосов
/ 13 апреля 2010

TreeViews работают по-другому. Элементы внутри HierarchicalDataTemplate являются TreeViewItems, и любой элемент управления, указанный вами в HierarchicalDataTemplate, будет функционировать в качестве его заголовка. Итак, в основном вы указываете, что элементы в вашем TreeView являются 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;
        }
    }
}
...