سؤال

I have an ItemsControl, which is bound to a collection, and I specify a HierarchicalDataTemplate to render the items. I got a template selector as well since the rendering for individual items are going to wary. For some reason this does not work.

Below is an extract of the code, can you please help? I'm looking to render items from the following hierarchy Parent->Child Collection->SubChildCollection (as in the below code).

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfApplication2="clr-namespace:WpfApplication2" Title="MainWindow" Height="350" Width="525">
    <Window.Resources>

        <DataTemplate x:Key="EntityItemTemplate" DataType="{x:Type WpfApplication2:EntityItem}">
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
        <WpfApplication2:TemplateSelector x:Key="ts" EntityItemTemplate="{StaticResource EntityItemTemplate}"/>        
        <HierarchicalDataTemplate x:Key="hdt" DataType="{x:Type WpfApplication2:EntityGroup}" ItemsSource="{Binding Path=EntityItems}" ItemTemplateSelector="{StaticResource ts}"/>
    </Window.Resources>

    <Grid>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ItemsControl Grid.Row="0" ItemsSource="{Binding Path=Entity.EntityGroups}" ItemTemplate="{StaticResource hdt}"></ItemsControl>
    </Grid>
</Window>

public partial class MainWindow : Window
    {
        ViewModel vm = new ViewModel();
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = vm;
            vm.Entity = new Entity()
                            {
                                Name = "abc",
                                EntityGroups = new ObservableCollection<EntityGroup>()
                                                   {
                                                       new EntityGroup()
                                                           {
                                                               EntityItems = new ObservableCollection<EntityItem>()
                                                                                 {
                                                                                     new EntityItem() {Name = "Entity1"},
                                                                                     new EntityItem() {Name = "Entity2"}
                                                                                 }
                                                           }
                                                   }
                            };
        }

    }

    public class TemplateSelector:DataTemplateSelector
    {
        public DataTemplate EntityItemTemplate { get; set; }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (item == null || !(item is EntityItem))
                return base.SelectTemplate(item, container);

            return EntityItemTemplate;
        }
    }

    public class ViewModel:NotificationObject
    {
        private Entity _entity;
        public Entity Entity
        {
            get { return _entity; }
            set
            {
                _entity = value;
                RaisePropertyChanged(() => Entity); 
            }
        }
    }

    public class Entity:NotificationObject
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                RaisePropertyChanged(() => Name);   
            }
        }

        private ObservableCollection<EntityGroup> _entityGroups;
        public ObservableCollection<EntityGroup> EntityGroups
        {
            get { return _entityGroups; }
            set
            {
                _entityGroups = value;
                RaisePropertyChanged(() => EntityGroups);   
            }
        }
    }

    public class EntityGroup:NotificationObject
    {
        public string Name { get; set; }

        private ObservableCollection<EntityItem> _entityItems;
        public ObservableCollection<EntityItem> EntityItems
        {
            get { return _entityItems; }
            set
            {
                _entityItems = value;
                RaisePropertyChanged(() => EntityItems);    
            }
        }
    }

    public class EntityItem:NotificationObject
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                RaisePropertyChanged(() => Name);   
            }
        }
    }
هل كانت مفيدة؟

المحلول

Because you're using it in an ItemsControl, you shouldn't use a HierarchicalDataTemplate. As MSDN states, a HierarchicalDataTemplate:

Represents a DataTemplate that supports HeaderedItemsControl, such as TreeViewItem or MenuItem.

An ItemsControl shows its data inside a ContentPresenter. A TreeView will generate TreeViewItems, and a Menu will generate MenuItems.

If you want to use a DataTemplateSelector to display different templates for items in the ItemsControl, just set it directly as the ItemTemplateSelector:

<ItemsControl ItemsSource="{Binding Path=Entity.EntityGroups}" 
              ItemTemplateSelector="{StaticResource ts}" />

If you want a hierarchical display of your data, use a TreeView:

<TreeView ItemsSource="{Binding Path=Entity.EntityGroups}" 
          ItemTemplate="{StaticResource hdt}" />
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top