none
Model for items in TreeView RRS feed

  • Question

  • Hi Everybody !

    I have some difficulties with the component TreeView in WPF and I need your help.
    I have some items in a TreeView as below :

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="453" Width="855">
        <Grid>
            <TreeView Height="349" HorizontalAlignment="Left" Margin="12,12,0,0" Name="treeView1" VerticalAlignment="Top" Width="288">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <Image Source="Images/internetexplorer.png" Width="32" Height="32" />
                        <WrapPanel Orientation="Vertical" Grid.Column="1">
                            <Label Content="INTERNET EXPLORER" Width="auto" Height="auto" Padding="0" />
                            <Label Content="WebBrowser" Width="auto" Height="auto" Padding="0" />
                        </WrapPanel>
                    </Grid>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Image Source="Images/remotedesktop.png" Width="32" Height="32" />
                            <WrapPanel Orientation="Vertical" Grid.Column="1">
                                <Label Content="REMOTE DESKTOP CONNECTION" Width="auto" Height="auto" Padding="0" />
                                <Label Content="RDP client" Width="auto" Height="auto" Padding="0" />
                            </WrapPanel>
                        </Grid>
            </TreeView>
            <WindowsFormsHost Height="390" HorizontalAlignment="Left" Margin="306,12,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="515" />
        </Grid>

    In the future, I will complete my TreeView with a list of custom objects and I would like to know if there is a way to create a "model" I can apply to each item. I don't want to create a Grid, a WrapPanel, two Labels each time I'll add an item. The documents I found on the Web are too difficult to understand.

    Thanks in advance for your help.

    Thursday, May 31, 2012 11:07 AM

Answers

  • Normally this is done with data templates and data bindings. First let's see how the data template looks:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="453" Width="855">
        <Window.Resources>
            <DataTemplate x:Key="ModelTemplate">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Image Source="{Binding Image}" Width="32" Height="32" />
                    <WrapPanel Orientation="Vertical" Grid.Column="1">
                        <Label Content="{Binding Name}" Padding="0" />
                        <Label Content="{Binding Type}" Padding="0" />
                    </WrapPanel>
                </Grid>
            </DataTemplate>
        </Window.Resources>
        <Grid>
            <TreeView Height="349"
                      HorizontalAlignment="Left"
                      Margin="12,12,0,0"
                      Name="treeView1"
                      VerticalAlignment="Top"
                      Width="288"
                      ItemTemplate="{StaticResource ModelTemplate}" />
        </Grid>
    </Window>

    The data template is very similar to your existing item XAML except that now instead of hardcoded strings like "INTERNET EXPLORER" it uses data bindings like {Binding Name}. The TreeView itself doesn't contains any items anymore but instead it specifies what template to use for items by using the ItemTemplate property.

    For a data template to be of any use we need some data that it can bind to. We need a class that has the necessary properties: Name, Type and Image. So let's add a class to the project (I'll call it Shortcut because those items remind me of windows shortcuts but you can use any name you find suitable). Nothing special, just 3 string properties to hold the data for each item:

        public class Shortcut {
            public string Name {
                get;
                set;
            }
            public string Type {
                get;
                set;
            }
            public string Image {
                get;
                set;
            }
        }

    The only thing left to do now is to populate the TreeView with items. For this we'll create a collection (I'll just use an array for simplicity) of Shortcuts and set the ItemsSource property of the TreeView to this collection. You can place this code in MainWindow's constructor:

                treeView1.ItemsSource = new[] { 
                    new Shortcut{
                        Name = "INTERNET EXPLORER",
                        Type = "WebBrowser",
                        Image = "Images/internetexplorer.png"
                    }, 
                    new Shortcut {
                        Name = "REMOTE DESKTOP CONNECTION",
                        Type = "RDP client",
                        Image="Images/remotedesktop.png"
                    }
                };
    And that's it. When you want to add another item all you need to do is to add a new Shortcut { Name = "foo", Type ="bar", Image = "foobar" } to that array and it just works.
    • Marked as answer by NicolasC Thursday, May 31, 2012 12:30 PM
    Thursday, May 31, 2012 11:37 AM
    Moderator

All replies

  • Normally this is done with data templates and data bindings. First let's see how the data template looks:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="453" Width="855">
        <Window.Resources>
            <DataTemplate x:Key="ModelTemplate">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Image Source="{Binding Image}" Width="32" Height="32" />
                    <WrapPanel Orientation="Vertical" Grid.Column="1">
                        <Label Content="{Binding Name}" Padding="0" />
                        <Label Content="{Binding Type}" Padding="0" />
                    </WrapPanel>
                </Grid>
            </DataTemplate>
        </Window.Resources>
        <Grid>
            <TreeView Height="349"
                      HorizontalAlignment="Left"
                      Margin="12,12,0,0"
                      Name="treeView1"
                      VerticalAlignment="Top"
                      Width="288"
                      ItemTemplate="{StaticResource ModelTemplate}" />
        </Grid>
    </Window>

    The data template is very similar to your existing item XAML except that now instead of hardcoded strings like "INTERNET EXPLORER" it uses data bindings like {Binding Name}. The TreeView itself doesn't contains any items anymore but instead it specifies what template to use for items by using the ItemTemplate property.

    For a data template to be of any use we need some data that it can bind to. We need a class that has the necessary properties: Name, Type and Image. So let's add a class to the project (I'll call it Shortcut because those items remind me of windows shortcuts but you can use any name you find suitable). Nothing special, just 3 string properties to hold the data for each item:

        public class Shortcut {
            public string Name {
                get;
                set;
            }
            public string Type {
                get;
                set;
            }
            public string Image {
                get;
                set;
            }
        }

    The only thing left to do now is to populate the TreeView with items. For this we'll create a collection (I'll just use an array for simplicity) of Shortcuts and set the ItemsSource property of the TreeView to this collection. You can place this code in MainWindow's constructor:

                treeView1.ItemsSource = new[] { 
                    new Shortcut{
                        Name = "INTERNET EXPLORER",
                        Type = "WebBrowser",
                        Image = "Images/internetexplorer.png"
                    }, 
                    new Shortcut {
                        Name = "REMOTE DESKTOP CONNECTION",
                        Type = "RDP client",
                        Image="Images/remotedesktop.png"
                    }
                };
    And that's it. When you want to add another item all you need to do is to add a new Shortcut { Name = "foo", Type ="bar", Image = "foobar" } to that array and it just works.
    • Marked as answer by NicolasC Thursday, May 31, 2012 12:30 PM
    Thursday, May 31, 2012 11:37 AM
    Moderator
  • Hi Mike,

    Thanks a lot for your help. It is exactly that I was looking for.

    Goodbye,
    NicolasC

    Thursday, May 31, 2012 12:30 PM