Next I will show you how to bind properties of a DataGrid row to a property of an entity. The commonest situation where you would want to do this is when you want to vary the background color of a row by the value in one of the fields, for example a status field.
Let’s try it with a concrete example: I’ve got an entity called CustomerSatisafaction which contains scores customers have given for certain aspects of our business. Scores are 0 to 5 where 5 is very good, 4 and above is good, 3 and above is ok, below 3 is failed.
First thing we have to do is bind the entity to the DataGrid, but that shouldn’t be a problem. Next we will need to create another one-way ValueConverter to convert our scores into colors that we can use as background colors – I suggest you keep these colors quite pale, otherwise you will not be able to read the cell content.
public class RowColorConverter : IValueConverter
{
public RowColorConverter() { }
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
int score = (int) value;
if (score >= 5)
{
// Great scrore! Green all te way.
return new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 200, 255, 200));
}
else if (score >= 4)
{
// Good, but could do better. Pale green
return new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 220, 250, 220));
}
else if (score >= 3)
{
// Only just made it. Pale yellow
return new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 250, 250, 220));
}
else
{
// That’s no good. Pale red
return new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 250, 220, 220));
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
Next comes the tricky bit: how to databind the background of a DataGrid row. I’ve seen many attempts at it but the easiest way to do it, I think, is in code.
The only moment you get access to the properties of an individual row in code is while it is being created. The event we need to handle on the DataGrid to get access to the background propery is LoadingRow. This works perfectly for one-time binding, but I would like the color to change along with the value. To do this, you will als need to reapply the row template every time the row is edited. You can easily do this by calling OnApplyTemplate() on the row during the CellEditEnded event of the DataGrid.
public partial class myPage : Page
{
RowColorConverter rowColorConverter;
myPage()
{
InitializeComponent();
rowColorConverter = new RowColorConverter();
page.myGrid.LoadingRow += new EventHandler(myGrid_LoadingRow);
page.myGrid.CellEditEnded += new EventHandler(myGrid_CellEditEnded);
}
void myGrid_CellEditEnded(object sender, DataGridCellEditEndedEventArgs e)
{
e.Row.OnApplyTemplate();
}
void myGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
Binding b = new Binding("myProperty")
{
Mode = BindingMode.OneWay,
Converter = rowColorConverter,
ValidatesOnExceptions = true
};
e.Row.SetBinding(DataGridRow.BackgroundProperty, b);
}
}
The exact same principal can be applied to any other property of a DataGrid row, like the border color, so you can draw you user’s attention to an abnormal cell value when needed or grading scores as I’ve done in this example.
Databinding in SilverLight is a really powerfull concept and it’s well worth exploring ValueConverters and databinding for many common tasks you would do with events and code behind in WinForms.
By Nick Verschueren, .Net Solutions Architect