2

So, the following is easy enough in WPF, but how would you do it in Silverlight?

Please note that the trick here is to display both Groups, and Entries on the same level. Additonally you dont know how deep the entries are nested, they might be on the first, or the nth level. This is hard in Silverlight because you lack the DataType="{x:Type local:Group}" property in the H.DataTemplate (or any DataTemplate). Building my own custom DataTempalteSelector also didnt work, because the Hierarchial ItemsSource gets lost. (Which just gave me a new idea which I will investigate shortly)


Example:

Group1
--Entry
--Entry
Group2
--Group4
----Group1
------Entry
------Entry
----Entry
----Entry
--Entry
--Entry
Group3
--Entry
--Entry

Your Classes:

public class Entry
{
    public int Key { get; set; }
    public string Name { get; set; }
}

public class Group
{
    public int Key { get; set; }
    public string Name { get; set; }

    public IList<Group> SubGroups { get; set; }
    public IList<Entry> Entries { get; set; }
}

Your xaml:

   <TreeView Name="GroupView" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding}">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type local:Group}" ItemsSource={Binding Items}">
                <TextBlock Text="{Binding Path=Name}" />
            </HierarchicalDataTemplate>
            <DataTemplate DataType="{x:Type local:Entry}" >
                <TextBlock Text="{Binding Path=Name}" />
            </DataTemplate>
        </TreeView.Resources>
    </TreeView>
AGhosT
  • 113
  • 1
  • 11
  • Does this ItemsSource="{Binding Items}" really work in WPF? What are this "Items"? – alpha-mouse Nov 30 '10 at 22:52
  • Good point, I didnt test it myself, I jsut referred to this post: http://stackoverflow.com/questions/4150334/treeview-binding where that snippet was given as the answer. – AGhosT Dec 02 '10 at 11:07
  • I suppos Items should just be changed to SubGroups (And the Binding in the TreeView should be to an obs.collection) – AGhosT Dec 02 '10 at 11:08
  • You should probably make the comment where you mention your solution into an answer, and mark it as the answer. – Jon Onstott Mar 07 '11 at 02:01

2 Answers2

0

The TreeView control from the Silverlight toolkit supports hierarchical data templates.

Check out this article for sample usage, but it looks identical to me to the WPF built in one.

You can download the Silverlight toolkit here.

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • Hi, I am aware of that, but you seemed to miss the tricke here. What I am trying to do is display to different entities on the same level of the datatemplate, which is where is failed. – AGhosT Dec 02 '10 at 10:55
  • 2
    In the end I had build up a new hierarchy in my ViewModel, containing both the entities and groups wrapped in a new Node class, which contains a collection of Subnodes, and an "Entity" which contains the actual Entity I am trying to display. Then the xaml becomes straightforward with just one itemsource for the h.datatemplate. – AGhosT Dec 02 '10 at 10:59
  • @AGhost, could you provide some demo xaml and source for your solution to this problem and mark it as answer? I also have the same problem. – themaestro Jun 06 '11 at 23:21
0

Here is an example of using the HierarchicalDataTemplate with a HeaderedItemsControl in Silverlight (Songhay.Silverlight.BiggestBox.Views.ClientView.xaml):

<UserControl x:Class="Songhay.Silverlight.BiggestBox.Views.ClientView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"
    xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" 
    xmlns:sdk="clr-namespace:System.Windows;assembly=System.Windows.Controls"
    xmlns:sdkctrls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"
    xmlns:v="clr-namespace:Songhay.Silverlight.BiggestBox.Views"
    xmlns:m="clr-namespace:Songhay.Silverlight.BiggestBox.ViewModels">
    <UserControl.Resources>

        <Style x:Key="StackPanelRoot" TargetType="StackPanel">
            <Setter Property="Background" Value="Seashell" />
            <Setter Property="Height" Value="598" />
            <Setter Property="Width" Value="1024" />
        </Style>

        <Style x:Key="GridRoot" TargetType="Grid">
            <Setter Property="Height" Value="570" />
        </Style>

        <Style x:Key="ClientGridSplitter" TargetType="sdkctrls:GridSplitter">
            <Setter Property="Background" Value="#FFE0EEE0" />
            <Setter Property="Height" Value="8" />
            <Setter Property="HorizontalAlignment" Value="Stretch" />
        </Style>

        <m:ClientViewModel x:Key="ClientViewModelDataSource" d:IsDataSource="True"/>

        <Style TargetType="sdkctrls:HeaderedItemsControl">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="sdkctrls:HeaderedItemsControl">
                        <StackPanel>
                            <ItemsPresenter Margin="10,0,0,0" />
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="ScrollViewerIndexItems" TargetType="ScrollViewer">
            <Setter Property="Margin" Value="10" />
            <Setter Property="VerticalScrollBarVisibility" Value="Auto" />
        </Style>

        <Style x:Key="StackPanelIndexItems" TargetType="StackPanel">
            <Setter Property="Background" Value="#ff9" />
            <Setter Property="Orientation" Value="Horizontal" />
        </Style>

    </UserControl.Resources>

    <UserControl.DataContext>
        <Binding Source="{StaticResource ClientViewModelDataSource}"/>
    </UserControl.DataContext>

    <Border BorderBrush="Black" BorderThickness="1" VerticalAlignment="Center">
        <StackPanel x:Name="RootPanel" Style="{StaticResource StackPanelRoot}">
            <Grid Style="{StaticResource GridRoot}">
                <Grid.RowDefinitions>
                    <RowDefinition MinHeight="128" MaxHeight="360" Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="1.5*" />
                </Grid.RowDefinitions>
                <v:HeaderView Grid.Row="0" />
                <sdkctrls:GridSplitter Grid.Row="1" Style="{StaticResource ClientGridSplitter}" />
                <StackPanel Grid.Row="2"
                    Orientation="Horizontal"
                    Style="{StaticResource StackPanelIndexItems}">
                    <ScrollViewer Style="{StaticResource ScrollViewerIndexItems}">
                        <sdkctrls:HeaderedItemsControl
                            Header="{Binding IndexTitle}"
                            ItemsSource="{Binding Outlines}">
                            <sdkctrls:HeaderedItemsControl.HeaderTemplate>
                                <DataTemplate>
                                    <TextBlock FontSize="24" FontWeight="Bold" Text="{Binding}" />
                                </DataTemplate>
                            </sdkctrls:HeaderedItemsControl.HeaderTemplate>
                            <sdkctrls:HeaderedItemsControl.ItemTemplate>
                                <sdk:HierarchicalDataTemplate>
                                    <StackPanel>
                                        <TextBlock FontSize="12" FontWeight="Bold" Margin="0,10,0,0" Text="{Binding Text}" />
                                        <sdkctrls:HeaderedItemsControl ItemsSource="{Binding Outlines}" Margin="10,0,10,0">
                                            <sdkctrls:HeaderedItemsControl.ItemTemplate>
                                                <sdk:HierarchicalDataTemplate>
                                                    <HyperlinkButton
                                                        ClickMode="Press"
                                                        Command="{Binding IndexItemCommand, Source={StaticResource ClientViewModelDataSource}}"
                                                        CommandParameter="{Binding Url}"
                                                        FontSize="12">
                                                        <HyperlinkButton.Content>
                                                            <TextBlock Text="{Binding Text}" />
                                                        </HyperlinkButton.Content>
                                                    </HyperlinkButton>
                                                </sdk:HierarchicalDataTemplate>
                                            </sdkctrls:HeaderedItemsControl.ItemTemplate>
                                        </sdkctrls:HeaderedItemsControl>
                                    </StackPanel>
                                </sdk:HierarchicalDataTemplate>
                            </sdkctrls:HeaderedItemsControl.ItemTemplate>
                        </sdkctrls:HeaderedItemsControl>
                    </ScrollViewer>
                    <navigation:Frame x:Name="IndexFrame" Width="685">
                    </navigation:Frame>
                </StackPanel>
            </Grid>
            <v:FooterView Height="30" />
        </StackPanel>
    </Border>
</UserControl>
rasx
  • 5,288
  • 2
  • 45
  • 60
  • Hi, you also seemed to miss the point. I am trying to bind to a class who possibly needs to display two sets of entities SubGroups, and Entries, on the same level. In the end I had to wrap these classes manually in Nodes, as outlined ain my other comment. But thx for trying. – AGhosT Dec 02 '10 at 11:02
  • Sorry, I should have made the question clearer, I will rectify it now. – AGhosT Dec 02 '10 at 11:41