Developers are often in need to link the data between two controls. Any changes done in one control should get updated in the other control. Now this is not something new and is implemented from long by using a common Data Source between the controls. Any changes from either of the controls are propagated to the other associated control.

The objective of the blog is to use this concept to generate dynamic C1TabItems based on the number of Rows in C1DataGrid for Silverlight. Addition of new Rows in C1DataGrid, append a new C1TabItem in C1TabControl. Similarly deletion of rows or updating of cell values, removes the existing C1TabItems or their Header text respectively. This blog provides a combo box in the column bound to the Header Text of C1TabItem. Changes in value of a cell updates the corresponding C1TabItem Header Text.

This blog implementation makes use of ItemTemplate and ContentTemplate property for C1TabControl to define the bindings to the Data Source. Lets quickly go through the various steps involved in this implementation.

To begin with, create a small Class definition to be used as the binding structure. Its important that this Class should implement the INotifyPropertyChanged Interface.


public class MyDataClass : INotifyPropertyChanged
{
private string _dept;
public string Department
{
get { return _dept; }
set
{
_dept = value;
OnPropertyChanged("Department");
}
}

private int _deptValue;
public int DeptValue
{
get { return _deptValue; }
set
{
_deptValue = value;
OnPropertyChanged("DeptValue");
}
}

public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}



Create a Collection object to be used as a Data Source for the controls.


ObservableCollection<MyDataClass> myDataList = new ObservableCollection<MyDataClass>();
myDataList.Add(new MyDataClass() { Department = "Accounts", DeptValue = 1001 });
myDataList.Add(new MyDataClass() { Department = "Sales", DeptValue = 1004 });
myDataList.Add(new MyDataClass() { Department = "IT", DeptValue = 1003 });

this.c1DataGrid1.AutoGenerateColumns = false;
this.c1DataGrid1.ItemsSource = myDataList;
this.c1TabControl1.ItemsSource = myDataList;



Next step is to define a list of values to be used a ItemSource for the DataGridComboBoxColumn.



public class ComboData
{
public List<String> _lst;

public ComboData()
{
_lst = new List<string>();
}

public List<string> DataList
{
get
{
_lst.Add("Accounts");
_lst.Add("HR");
_lst.Add("IT");
_lst.Add("Sales");
_lst.Add("Training");

return _lst;
}
}
}



This completes the Code Behind implementation. Now move on to the XAML section, where all the bindings have to be done.

Binding C1DataGrid


<Grid.Resources>
<local:ComboData x:Key="cmbData"/>
</Grid.Resources>

<c1grid:C1DataGrid Name="c1DataGrid1" Grid.Row="1" >
<c1grid:C1DataGrid.Columns>
<c1grid:DataGridComboBoxColumn Header="Deparment" ItemsSource="{Binding Source={StaticResource cmbData}, Path=DataList}" Binding="{Binding Path=Department,Mode=TwoWay}"/>
<c1grid:DataGridNumericColumn Header="Deparment Code" Binding="{Binding DeptValue, Mode=TwoWay}"/>
</c1grid:C1DataGrid.Columns>
</c1grid:C1DataGrid>

Binding C1TabControl and Defining Templates



<c1:C1TabControl Name="c1TabControl1" Grid.Row="2">
<c1:C1TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Department}"/>
</DataTemplate>
</c1:C1TabControl.ItemTemplate>

<c1:C1TabControl.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding DeptValue}"/>
</DataTemplate>
</c1:C1TabControl.ContentTemplate>
</c1:C1TabControl>



Threading all the above code blocks together in one project would get you the complete implementation. Download the attached samples for your reference.

Download C# Sample
Download VB.Net Sample