Dynamic DataTemplates based on bound data

6 posts, 1 answers
  1. Rappen
    Rappen avatar
    11 posts
    Member since:
    Feb 2010

    Posted 24 Feb 2010 Link to this post

    Hi

    I am using a PanelBar with HierarcicalDataTemplate, and would like to define different ItemTemplates, and use them based on some data bound to the control.

    XAML:

    <Border Margin="0">
    <Border.Resources>
    <DataTemplate x:Key="CheckItem">
    <StackPanel Orientation="Horizontal" Margin="10 0 0 0">
    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Margin="0 0 5 0" Click="Checkbox_Click" />
    <TextBlock Name="txtCriteria" Text="{Binding Description}" HorizontalAlignment="Left" MouseDown="TextBlock_MouseDown" Cursor="{Binding LinkCursor}" />
    </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="TextItem">
    <StackPanel Orientation="Horizontal" Margin="10 0 0 0">
    <TextBlock Text="{Binding Description}" HorizontalAlignment="Left" />
    <TextBox Width="50" HorizontalAlignment="Right" />
    </StackPanel>
    </DataTemplate>
    <HierarchicalDataTemplate x:Key="Category" ItemsSource="{Binding Items}" ItemTemplate="{StaticResource CheckItem}">
    <StackPanel Orientation="Horizontal" Margin="0">
    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" IsThreeState="True" Margin="0 4 5 6" Click="CategoryCheckbox_Click" />
    <TextBlock Text="{Binding Description}" Height="13" Margin="5 4 5 6" HorizontalAlignment="Left"/>
    </StackPanel>
    </HierarchicalDataTemplate>
    </Border.Resources>
    <Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="10">
    <telerik:RadComboBox Name="rcbDefinition" Margin="0,0,0,0" Height="20"
    HorizontalAlignment="Stretch" VerticalAlignment="Top"
    SelectionChanged="rcbDefinition_SelectionChanged" FontSize="12" />
    <telerik:RadPanelBar BorderThickness="1" BorderBrush="#FF6699CC" Name="rpbSearchCategories" Margin="0,80,0,0" Width="250" HorizontalAlignment="Left"
    ExpandMode="Single" ItemTemplate="{StaticResource Category}" Expanded="rpbSearchCategories_Expanded" Background="White" />
    </Grid>
    </Border>

    codebehind:
    ...

    rcbDefinition.ItemsSource = SearchConfig.Items;
    ...

            private void rcbDefinition_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                SearchDefinition srchDef = (SearchDefinition)rcbDefinition.SelectedItem;
                if (srchDef.Items == null)
                    srchDef.LoadItems();
                rpbSearchCategories.ItemsSource = srchDef.DisplayItems;
                txtSubHeader.Text = srchDef.Instructions;
                UpdateQuery();
            }

     

    I defined two DataTemplates, one called CheckItem and one TextItem.
    What I would like to accomplish is to define which one to use, based on a field on the SearchDefinition.DisplayItem class.

    Taking a wild shot, I would write something like this:

    <HierarchicalDataTemplate x:Key="Category" ItemsSource="{Binding Items}" ItemTemplate="{Binding CategoryType}">

    But realizing this was too wild a shot.

    The "CategoryType" field on the Categories in the list Items would then return either "CheckItem" or "TextItem", depending on whether the underlying items should have a checkbox or a textbox for input by the user.

    I hope my question i clear enough for someone to give me a hint on how to do this!

    Regards
    Jonas

  2. Answer
    Tihomir Petkov
    Admin
    Tihomir Petkov avatar
    576 posts

    Posted 24 Feb 2010 Link to this post

    Hello Jonas,

    You can use a TemplateSelector:
    http://www.telerik.com/help/silverlight/styling-apperance-templating-selectors.html
    http://msdn.microsoft.com/en-us/library/ms742521.aspx

    All the best,
    Tihomir Petkov
    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
  4. Rappen
    Rappen avatar
    11 posts
    Member since:
    Feb 2010

    Posted 02 Mar 2010 Link to this post

    Hi!

    Looked at the links - now not using the TemplateSelector-approach, but finally got the bits together and I am now creating DataTemplates based on class name of bound data.
    Working like a charm!

    /Jonas
  5. Tihomir Petkov
    Admin
    Tihomir Petkov avatar
    576 posts

    Posted 03 Mar 2010 Link to this post

    Hello Jonas,

    TemplateSelectors are the mechanism provided by the platform, but of course you are in no way obliged to use them. I'm glad you got things to work.

    Greetings,
    Tihomir Petkov
    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.
  6. Eli Perp
    Eli Perp avatar
    5 posts
    Member since:
    Aug 2009

    Posted 13 Apr 2010 Link to this post

    Hi Jonas,

    Would you mind posting some code to demostrate how you implemented this.

    Regards,
    Eli

  7. Rappen
    Rappen avatar
    11 posts
    Member since:
    Feb 2010

    Posted 13 Apr 2010 Link to this post

    Hi Eli

    (And perhaps Telerik are also interrested in this snippet and how I solved it...)

    Here is some code...

    Template XAML:
        <Page.Resources> 
            <DataTemplate DataType="{x:Type local:SearchCriteriaCheck}">  
                <StackPanel Orientation="Horizontal" Margin="10 0 0 0" HorizontalAlignment="Stretch">  
                    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Margin="0 0 5 0" Click="Checkbox_Click" /> 
                    <TextBlock Name="txtCriteria" Text="{Binding Description}" HorizontalAlignment="Left" /> 
                    <Image Source="/Cinteros.CRM.CintSearch;component/Resources/open_new5.gif" Margin="10,0,0,0" Stretch="None" 
                           Cursor="Hand" MouseDown="TextBlock_MouseDown" Visibility="{Binding LinkVisible}" ToolTip="{Binding LinkTooltip}" /> 
                </StackPanel> 
            </DataTemplate> 
            <DataTemplate DataType="{x:Type local:SearchCriteriaText}">  
                <StackPanel Orientation="Horizontal" Margin="10,0,0,0" HorizontalAlignment="Stretch">  
                    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Margin="0 0 5 0" VerticalAlignment="Center" Click="Checkbox_Click" IsEnabled="{Binding CheckEnabled}" /> 
                    <StackPanel Orientation="Vertical" Margin="0 0 0 0" HorizontalAlignment="Stretch">  
                        <TextBlock Text="{Binding Description}" HorizontalAlignment="Left" Margin="0,0,0,0" /> 
                        <TextBox Width="170" HorizontalAlignment="Left" Text="{Binding Text, Mode=TwoWay}" TextChanged="TextBox_TextChanged"/>  
                    </StackPanel> 
                </StackPanel> 
            </DataTemplate> 
            <DataTemplate DataType="{x:Type local:SearchCriteriaDate}">  
                <StackPanel Orientation="Horizontal" Margin="10,0,0,0" HorizontalAlignment="Stretch">  
                    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Margin="0 0 5 0" VerticalAlignment="Center" Click="Checkbox_Click" /> 
                    <StackPanel Orientation="Vertical" Margin="0 0 0 0" HorizontalAlignment="Stretch">  
                        <TextBlock Text="{Binding Description}" HorizontalAlignment="Left" Margin="0,0,0,0" /> 
                        <telerik:RadDatePicker Width="170" SelectedDate="{Binding Date, Mode=TwoWay}" CalendarClosed="RadDatePicker_CalendarClosed" KeyDown="RadDatePicker_KeyDown" /> 
                    </StackPanel> 
                </StackPanel> 
            </DataTemplate> 
            <HierarchicalDataTemplate DataType="{x:Type local:SearchCategory}" ItemsSource="{Binding Items}">  
                <StackPanel Orientation="Horizontal" Margin="0">  
                    <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" IsThreeState="True" Margin="0 4 5 6" Click="CategoryCheckbox_Click"   
                              Visibility="{Binding CheckVisibility}" /> 
                    <TextBlock Text="{Binding Description}" Margin="5 4 5 6"/>  
                </StackPanel> 
            </HierarchicalDataTemplate> 
        </Page.Resources> 
     

    Design XAML:
            <Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="0" DataContext="{Binding ElementName=rcbDefinition, Path=SelectedItem}">  
                <telerik:RadComboBox Grid.Row="1" Grid.Column="0" Name="rcbDefinition" Margin="10,10,10,0" SelectionChanged="rcbDefinition_SelectionChanged" FontSize="12" /> 
                <telerik:RadPanelBar Grid.Row="2" Grid.Column="0" Grid.RowSpan="2" Margin="10" BorderThickness="1" BorderBrush="#FF6699CC" Name="rpbSearchCategories"   
                                     HorizontalAlignment="Stretch" ExpandMode="Single" Expanded="rpbSearchCategories_Expanded" Background="White"   
                                     ItemsSource="{Binding DisplayItems}" /> 
            </Grid> 

    The DisplayItems collection that is bound to the RadPanelBar ItemsSource are of class SearchCategory, templated by the hierarchicaltemplate above.
    The Items collection on the SearchCategory class are of either of the classes SearchCriteriaCheck, SearchCriteriaText or SearchCriteriaDate and will use their corresponding templates defined in the Page.Resources section.  

    With this approach there is no need at all for any code-behind as far as databinding and templating is concerned!

    Good luck :)

    /Jonas
Back to Top
UI for WPF is Visual Studio 2017 Ready