You are asked to create a Silverlight application to show a grid where one or more columns are combo boxes. This is a very common scenario. It can be very easily solved by creating a data edit template on the grid column and show a combo box, with a converter. There are lots of examples for this scenario, one in code project and another one in Manish blog. When I binged, there are lot of information in stack overflow. There is a much better solution if you are using Component One.
If you have component one, then we can remove all these data template, combo box and converters with simple property called Value Converter. Lets see the problem statement. We need to create a grid, with employee name and job title.
When you enter title in edit mode, it show available jobs like the following
Nothing special here, it is the standard combo box which shows all the available jobs for user to pick from. So how do we solve this problem using the special Value Converter?
Lets start from ViewModel this time.
- public List<Person> People
- {
- get
- {
- List<Person> list = new List<Person>();
- list.Add(new Person { ID = 1, Name = "Ajay", JobID = 1 });
- list.Add(new Person { ID = 2, Name = "Jeeem", JobID = 2 });
- return list;
- }
- }
Nothing new in the view model, it is same as you would build a collection in any other program. How about View?
- <c1:C1FlexGrid Name="_flex" ItemsSource="{Binding People}" AutoGenerateColumns="False">
- <c1:C1FlexGrid.Columns>
- <c1:Column Binding="{Binding Name}"/>
- <c1:Column Binding="{Binding JobID, Mode=TwoWay}" Header="Title"/>
- </c1:C1FlexGrid.Columns>
- </c1:C1FlexGrid>
Look at that, there is nothing special here either. We have a grid with two columns, first column is name and second column is Job ID. Please note that, we are not using combo box here. Ok so far we did not do anything new and I still want a combo box in second column. Lets go to the view code behind, that’s where the magic happens.
- public Dictionary<int, string> dict = new Dictionary<int, string>();
- public MainPage()
- {
- InitializeComponent();
- dict.Add(1, "Manager");
- dict.Add(2, "Team Lead");
- _flex.Columns[1].ValueConverter = new ColumnValueConverter(dict);
- }
We first create a dictionary, where we are going to keep the options available to show in the combo box. Line 6 and 7 adds two job titles to the dictionary and finally in line 8, we say, for second column use the value converter and point to new instance Column Value Converter with dictionary collection. This informs flex grid that, this column needs to a combo box and use the dictionary to show the string value of the value bound to the column.
Look at the code, it is very simple and elegant. I really like the approach more than writing data template, converters etc.,
One things, I haven’t figured out yet is to bind the value converter directly to view model property. If we could do it, we can eliminate all code from code behind. If I find a solution, I will post it here.