Pages

Wednesday 18 April 2012

Bindings in Silverlight - DataGrid and Converters

Hi,   In this post, we will see how to manipulate the data which we send to the data grid which has a binding.

Consider this scenario.  You have data, which has marks from 0 to 50.  You want to represent the marks on the grid, with colors indicating performance.  For example, all marks lesser than 25 are displayed in Red, and the others are displayed in green.

To implement such a scenario, we can make use of the concept of converters. We take the bound value that is to be checked, and pass that to our user defined class . This class returns the appropriate converted value and the returned value is bound to the data grid.

There are a few simple steps to use converters successfully in your program.
1) Create a custom class, that implements the IValueConverter interface .
2) Write your custom logic within the convert method of the above class.
3) In xaml, create a resource for this class in the <UserControl.Resources> section.
4) Modify the DataTemplate for your Data Grid Columns explicitly.

Step 1 & 2 :  Lets create two classes , one is the user defined data class, and the other is the class which implements the converter.

   public class Vals
  {

    public int val1 { get; set; }
    public int val2 { get; set; }

    public Vals(int i1, int i2)
     {
       val1 = i1;
       val2 = i2;
     }

 }

    public class myDataConv : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int str = Int32.Parse(value.ToString());

            if (str > 25)
            {
                return "Green";
            }
            return "Red";
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }


 Step 3:

Add a namespace reference  in the main usercontrol definition tag along with the other references.

xmlns:alocal="clr-namespace:DemoDataGrid"


Then add the converter class in the <UserControl.Resources> tag.

<UserControl.Resources>
        <alocal:myDataConv x:Key="mystylekey"></alocal:myDataConv>
</UserControl.Resources>


Step 4:

Modify the data template of the DataGrid Column.

        <sdk:DataGrid AutoGenerateColumns="False" Height="170" HorizontalAlignment="Left" Margin="80,56,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="222" >
            <sdk:DataGrid.Columns>
                <sdk:DataGridTemplateColumn>
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding val1}"  Foreground="{Binding Path=val1, Converter={StaticResource mystylekey}}"></TextBlock>
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>

In the Xaml.cs  code file , bind a collection to the Data grid.

List<Vals> myD = new List<Vals>();

for(int i=0;i<20;i++)
{

   myD.add( new Vals(i*3,i*5) );

}

dataGrid1.ItemSource = myD;

 That's it.  The Data template is applied to the Data grid columns.  The Foreground property is bound to val1 , which is passed to the converter. The converter checks the value, and returns an appropriate color for this.


Another interesting aspect of using converters is the use of Converter Parameter .  We can add any string literal as a parameter to the converter in addition to the bound value from Path.  One thing to keep in mind is that only string literals are supported currently, and binding the converter parameter is not allowed.

Using the converter parameter is very simple. In the convert method in the Converter class, you will notice that the second parameter is Parameter.  You can make use of that, or leave it as it is.   And this is what you get as output after you use converters.





Try experimenting with different scenarios . Also, if possible, use a checkbox column, and try to enable disable the checkboxes based on bound values.   More of it in the next post of the series .

No comments:

Post a Comment