Binding with HierarchicalDataTemplate

2 posts, 0 answers
  1. nico
    nico avatar
    1 posts
    Member since:
    Jul 2010

    Posted 22 Jul 2010 Link to this post

    Hi,

    I've some problem with my treeview, idk if my problem is directly from the treeview or not.
    What i'ld like to do is somethink like this :
    - Website 1
    - Month A
    - picture 1
    - picture 2
    - Month B
    - picture 1
    - Website 2
    - Month A
    - picture 1

    The problem i've meet is that for all node "website", i've the same child nodes.
    Thx :)

    Here is my code :
    MainWindow.xaml
    <Window xmlns:my="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation"  x:Class="BonjourWPF.MainWindow"
            xmlns:local="clr-namespace:BonjourWPF"
            xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
            Title="MainWindow" Height="768" Width="1024">
        <Window.Resources>
            <local:WebSites x:Key="WebsiteCollection" />
     
            <CollectionViewSource
                x:Key="Sites"
                Source="{Binding Source={StaticResource WebsiteCollection}}">
            </CollectionViewSource>
            <CollectionViewSource
                                x:Key="GroupMonth"
                                Source="{Binding Source={StaticResource Sites},Path=Pictures}">
                <CollectionViewSource.SortDescriptions>
                    <scm:SortDescription PropertyName="date"></scm:SortDescription>
                </CollectionViewSource.SortDescriptions>
                <CollectionViewSource.GroupDescriptions>
                    <PropertyGroupDescription PropertyName="month" />
                </CollectionViewSource.GroupDescriptions>
            </CollectionViewSource>
        </Window.Resources>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="256" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid Grid.Row="0">
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition Height="256" />
                </Grid.RowDefinitions>
                <Grid.Resources>
                    <DataTemplate x:Key="Picture" DataType="Picture">
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding date, StringFormat={}{0:dd/MM/yyyy}}"  Foreground="Black" />
                        </StackPanel>
                    </DataTemplate>
     
                    <HierarchicalDataTemplate x:Key="Mois" ItemsSource="{Binding Path=Items}" ItemTemplate="{StaticResource Picture}">
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Name}" Foreground="Black" />
                        </StackPanel>
                    </HierarchicalDataTemplate>
     
                    <HierarchicalDataTemplate x:Key="Site" ItemsSource="{Binding Source={StaticResource GroupMonth},Path=Groups}"  ItemTemplate="{StaticResource Mois}">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="{Binding icon}" Margin="0,0,6,0"/>
                            <TextBlock Text="{Binding name}"  Foreground="Black" FontWeight="Bold"
                                FontSize="15" />
                        </StackPanel>
                    </HierarchicalDataTemplate>
     
                </Grid.Resources>
     
                <my:RadTreeView Name="RadTreeView1" ItemsSource="{Binding Source={StaticResource Sites}}" ItemTemplate="{StaticResource Site}" IsSingleExpandPath="True">
                </my:RadTreeView>
                 
            </Grid>
            <Image Grid.Column="1" Name="image1" Stretch="Uniform" />
        </Grid>
    </Window>


    public class WebSites : ObservableCollection<WebSite>
    {
        public WebSites()
        {
            this.Add(new WebSite()
            {
                id = 1,
                name = "Site 1",
                icon = "site1.ico"
            });
     
            this.Add(new WebSite()
            {
                id = 2,
                name = "Site 2",
                icon = "site2.ico"
            });
        }
    }

    public class Picture
    {
        public DateTime date { get; set; }
        public String year
        {
            get
            {
                return date.Year.ToString();
            }
        }
        public String month
        {
            get
            {
                return DateTimeFormatInfo.CurrentInfo.GetMonthName(date.Month);
            }
     
        }
        public String path { get; set; }
    }

        public class WebSite
        {
            public Int32 id { get; set; }
            public String name { get; set; }
            public String icon { get; set; }
     
            public WebSite()
            {
            }
     
     
            private ObservableCollection<Picture> _pictures;
            public ObservableCollection<Picture> Pictures
            {
                get {
                    if (_pictures == null)
                    {
                        _pictures = new ObservableCollection<Picture>();
                        if (Directory.Exists(name))
                        {
                            foreach (String file in Directory.GetFiles(name))
                            {
                                _pictures.Add(new Picture() { date = Convert.ToDateTime(Path.GetFileNameWithoutExtension(file)), path = Path.GetFullPath(file) });
                            }
                        }
                    }
                    return _pictures;
                }
                set
                {
                    _pictures = value;
                }
            }
    }
  2. Hristo
    Admin
    Hristo avatar
    352 posts

    Posted 23 Jul 2010 Link to this post

    Hi nico,

    I can provide you two solutions to your problem. I'm attaching you an archive containing three projects.

    The first one (_Bad) is similar to the code you posted.

    The second one (_InModel) demonstrates how to solve the problem with grouping done in the model (ViewModel). Take a look at the WebSite.cs file.
    public Object PicturesByMonth
    {
        get
        {
            var result =
                from p in Pictures
                group p by new { p.month } into pg
                select new { Month = pg.Key, Items = pg };
            return result;
        }
    }
    In the MainWindow.xaml file you can see that I'm using normal HierarchicalDataTemplates. Notice I'm using the PicturesByMonth property to define the ItemSource for second level.

    The third project (_ValueConverter) shows an alternative and uses IValueConverter interface to group the elements.
    public class MonthGroupingConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var result =
                from picture in value as IEnumerable<Picture>
                group picture by new { picture.month } into GroupedPictures
                select new { Month = GroupedPictures.Key, Items = GroupedPictures };
            return result;
            }
    ...
    MonthGroupingConverter is a custom defined class and you can change the grouping to fit your needs.

    Next I'm creating an instance of it in the main mxml file.
    ...
    <local:MonthGroupingConverter x:Key="MGC" />
    ...

    Finally I'm using that converter in the root level template to define ItemSource for second level.
    <HierarchicalDataTemplate x:Key="SiteTemplate"
            ItemsSource="{Binding Pictures,  Converter={StaticResource MGC}}"
            ItemTemplate="{StaticResource MonthsTemplate}">
        <TextBlock Text="{Binding name}" Foreground="Black" FontWeight="Bold" FontSize="15" />
    </HierarchicalDataTemplate>


    Sincerely yours,
    Hristo
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. UI for WPF is Visual Studio 2017 Ready
Back to Top