How To: Conditional Combo Cell Editor
C1Datagrid for Silverlight being a Data bound control is used heavily with the applications demanding user input. This interactivity is incorporated in form of various types of editors like textbox, numeric updown control or it could be a ComboBox which comes with either DataGridTextColumn, DataGridNumericColumn or DataGridComboBoxColumn. For specific requirements, DataGridTemplateColumn can be implemented which allows other controls like RichTextBox or other usercontrols to be used as editors. Now there could be a scenario where application requires input to be restricted or customized as per the row data. In this blog, I am implementing an example where Input has to be done through a ComboBox in a cell; however, the combobox will be available for specific rows. Apart from this it looks to provide Auto appending combo list where values inputted by the user is not available in the current list gets appended for future selection. Lets begin with the implementation......
Define DataSource for C1DataGrid
For this blog I am defining a simple Class structure. This does not have any specific affect on the actual implementation.
public class PersonName
{
private string firstName;
private string country;
public PersonName(string first, string cntry)
{
this.firstName = first;
this.country = cntry;
}
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string CountryName
{
get { return country; }
set { country = value; }
}
}
public class NameList : ObservableCollection
{
public NameList()
: base()
{
Add(new PersonName("Willa", "US"));
Add(new PersonName("Isak", "UK"));
Add(new PersonName("Victor", "India"));
Add(new PersonName("Jules", "Japan"));
}
}
Designing Custom Column
Customized column for this implementation inherits the default DataGridTextColumn. Along with this, it also defines a list of string to be displayed in the combobox. Now this list of string can be predefined or it could be retrieved at runtime. As of now, I have implented a pre-defined list of country names which will be used in the next section.
public class DataGridComboTextColumn : DataGridTextColumn
{
List cntryList = new List();
public DataGridComboTextColumn()
: base()
{
cntryList.Add("India");
cntryList.Add("US");
cntryList.Add("UK");
cntryList.Add("Japan");
cntryList.Add("China");
}
}
Implementing Functionality for Custom Column
This final section of the implementation overrides the following modules.
- GetCellEditingContent
- PrepareCellForEdit
Apart from this, important event added to this section is the EditCompleted event for the editing element ComboBox. In this event, input text in the Editable region of the combobox is checked for its existence in the current dropdown list. If the input text is not available, it is appended to the list for future selection. The following code modules show the required implementation.
public override FrameworkElement GetCellEditingContent(DataGridRow row)
{
if (row.Index % 2 == 0)
{
var cmb = new C1.Silverlight.C1ComboBox() { ItemsSource = cntryList, Text= (row.DataItem as PersonName).CountryName };
cmb.IsEditable = true;
cmb.Padding = new Thickness(0);
cmb.EditCompleted += cmb_EditCompleted;
cmb.Tag = (int)row.Index;
return cmb;
}
return new TextBox() { Text = (row.DataItem as PersonName).CountryName };
}
void cmb_EditCompleted(object sender, EventArgs e)
{
string editingvalue = (sender as C1.Silverlight.C1ComboBox).Text;
if (editingvalue != string.Empty)
if (!cntryList.Contains(editingvalue))
cntryList.Add(editingvalue);
int rowIndex=(int)(sender as C1.Silverlight.C1ComboBox).Tag;
(this.DataGrid.Rows[rowIndex].DataItem as PersonName).CountryName = editingvalue;
this.DataGrid.Rows[rowIndex].Refresh(false, true, false);
}
public override object PrepareCellForEdit(FrameworkElement editingElement)
{
if (editingElement.GetType().Equals(typeof(C1.Silverlight.C1ComboBox)))
{
string editingValue = ((SL\_DataGrid\_ComboInSpecificCells.PersonName)((editingElement as C1.Silverlight.C1ComboBox).DataContext)).CountryName;
(editingElement as C1.Silverlight.C1ComboBox).SelectedIndex = cntryList.IndexOf(editingValue);
}
return editingElement;
}
This running image shows the working demo for the above implementation. Refer to the attached sample for Complete implementation. Download Sample ControlExplorer for Silverlight sample contains demonstration for other customizations in C1DataGrid for Silverlight. Preview the implementations in the online demo from the given link. http://demo.componentone.com/silverlight/controlexplorer/#DataGrid/See%20it%20in%20action