Binding To Collection
The purpose of this tutorial is to show you how to bind a RadTabControl to a collection of business objects.
When you want the tabs of the RadTabControl to be automatically generated on the basis of a collection, use the ItemsSource property.
-
Create a new class named Person. The class' structure is shown on the next code-snippet.
Example 1: Creating Person class
public class Person { public Person( string name, int age ) { this.Name = name; this.Age = age; } public string Name { get; set; } public int Age { get; set; } }
Public Class Person Public Sub New(ByVal name As String, ByVal age As Integer) Me.Name = name Me.Age = age End Sub Private _Name As String Public Property Name() As String Get Return _Name End Get Set(ByVal value As String) _Name = value End Set End Property Private _Age As Integer Public Property Age() As Integer Get Return _Age End Get Set(ByVal value As Integer) _Age = value End Set End Property End Class
-
Create a new class named ViewModel, like the example below:
Example 2: Creating ViewModel class
public class ViewModel { public ViewModel() { this.Persons = new ObservableCollection<Person>(); this.Persons.Add( new Person( "Ivan", 23 ) ); this.Persons.Add( new Person( "Stefan", 34 ) ); this.Persons.Add( new Person( "Maria", 16 ) ); this.Persons.Add( new Person( "Michael", 78 ) ); } public ObservableCollection<Person> Persons { get; set; } }
Public Class ViewModel Public Sub New() Me.Persons = New ObservableCollection(Of Person)() Me.Persons.Add(New Person("Ivan", 23)) Me.Persons.Add(New Person("Stefan", 34)) Me.Persons.Add(New Person("Maria", 16)) Me.Persons.Add(New Person("Michael", 78)) End Sub Private _Persons As ObservableCollection(Of Person) Public Property Persons() As ObservableCollection(Of Person) Get Return _Persons End Get Set(ByVal value As ObservableCollection(Of Person)) _Persons = value End Set End Property End Class
As you can see the ViewModel class has a reference to an observable collection of Person objects. In fact this will be set to the ItemsSource property of the RadTabControl. Also that in the class' constructor the collection is initialized with some sample data.
-
Set the DataContext of the MainWindow.
Example 2: Setting DataContext
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.DataContext = new ViewModel(); } }
-
Set the ItemsSource property of the RadTabControl.
Example 3: Binding the ItemsSource Property
<telerik:RadTabControl x:Name="tabControl" ItemsSource="{Binding Source={StaticResource DataSource}, Path=Persons}"/>
Now when you run the demo the result should be similar to the next image.
The reason for this result is that the RadTabControl "still doesn't know" how to display these business objects. You need to "say" explicitly what to be displayed as a Header using either the DisplayMemberPath property or setting the HeaderTemplate property. Additionally you need to set a ContentTemplate.
-
Set the DisplayMemberPath property of the RadTabControl to "Name" and create custom DataTemplate for the ContentTemplate property.
Example 4: Binding the ItemsSource Property
<Window.Resources> <DataTemplate x:Key="ContentTemplate"> <Grid> <TextBlock Text="{Binding Age}"/> </Grid> </DataTemplate> </Window.Resources> <Grid x:Name="LayoutRoot" Background="White"> <telerik:RadTabControl x:Name="radTabControl" Margin="8" ItemsSource="{Binding Path=Persons}" DisplayMemberPath="Name" ContentTemplate="{StaticResource ContentTemplate}"/> </Grid>
The final result is shown on the next image:
When the ItemsSource is specified, RadTabItem containers are generated for each item in the collection. By using the template properties of the RadTabControl and the RadTabItem you can control the appearance and the visualization of the items in the collection.
Suppress Selected Content Template Reapplying
By default, the RadTabControl keeps one ContentPresenter for all its Items and reapplies its ContentPresenter.ContentTemplate on each selection change. In scenarios where the ItemsSource has changed runtime, it could lead to a performance hit. RadTabControl expose a SupressSelectedContentTemplateReapplying property which can be used to avoid this. By default this property is set to False along with the IsContentPreserved property. If you set it to True, then the RadTabControl will still have one ContentPresenter, but it won't reset its ContentTemplate whenever the selection is changed, and this will increase the performance when ItemsSource is changed runtime.
Please keep in mind that if you set the SupressSelectedContentTemplateReapplying property to True the same RadTabControl.ContentTemplate is applied to all RadTabItems. And if the ControlTemplate elements aren't databound, the same values will be displayed in all RadTabItems.