I am trying to make a very flexible binding situation for my XamGrid.Basically I want to make the Grid always dynamic. The amount of columns can vary depedning on the case and their Keys can change so I would like to dynamically build it all the time. It's not Hierarchial data, its a flat grid. So I just have a collection of rows that contain a collections of cells.
I want to have it two way bind to a collection at runtime. So based upon my collection I will build the the corresponding columns and bind to my rows collection.
Here's some code...
Class Row that contains the List of Cells for the respective Row
public class Row{
public Row() { Cells = new List<Cell>(); } public List<Cell> Cells { get; set; }}Class Cell that contains the data for the individual cell public class Cell { public string Value { get; set; } }
Initialize a test collection, create column datatemplates then add to columns to XamGrid, and set the XamGrid item source
int numOfColumns = 3;string[] keys = new string[] { "Key1", "Key2", "Key3" }; List<Row> Rows = new List<Row>(); for (int i = 0; i < 10; i++){ Row r = new Row(); for (int j = 0; j < numOfColumns; j++) { Cell c = new Cell(); c.Value = String.Format("Row {0} Cell {1}", i, j); r.Cells.Add(c); } Rows.Add(r);} for (int i = 0; i < numOfColumns; i++){ TemplateColumn column = new TemplateColumn(); column.ItemTemplate = Create(typeof(TextBox), String.Format("Cells[{0}].Value", i)); column.Key = keys[i]; XamGrid.Columns.Add(column);}XamGrid.ItemsSource = Rows; Here's the DataTemplate Create method I use public static DataTemplate Create(Type type, string path){ return (DataTemplate)XamlReader.Load( @"<DataTemplate xmlns=""http://schemas.microsoft.com/client/2007""> <" + type.Name + @" Text=""{Binding Path= "+ path + @", Mode=TwoWay}""/> </DataTemplate>");}
int numOfColumns = 3;string[] keys = new string[] { "Key1", "Key2", "Key3" }; List<Row> Rows = new List<Row>(); for (int i = 0; i < 10; i++){ Row r = new Row(); for (int j = 0; j < numOfColumns; j++) { Cell c = new Cell(); c.Value = String.Format("Row {0} Cell {1}", i, j); r.Cells.Add(c); } Rows.Add(r);} for (int i = 0; i < numOfColumns; i++){ TemplateColumn column = new TemplateColumn(); column.ItemTemplate = Create(typeof(TextBox), String.Format("Cells[{0}].Value", i)); column.Key = keys[i]; XamGrid.Columns.Add(column);}XamGrid.ItemsSource = Rows;
When I run this I get the following Error:
Unhandled Exceprion
Message: Infragistics.Controls.Grids.InvalidColumnKeyException: The following key(s) do not correspon with the DataSource: "Key1" If you'd like to add additional columns, please use the unbound column type....
I want to ensure I have TwoWay binding, so I definitely want to make sure my columns are binding in that mode.
So instead of TemplateColumn I change it to UnboundColumn and I no longer get the error,
for (int i = 0; i < numOfColumns; i++) { UnboundColumn column = new UnboundColumn(); //TemplateColumn column = new TemplateColumn(); column.ItemTemplate = Create(typeof(TextBox), String.Format("Cells[{0}].Value", i)); column.Key = keys[i]; XamGrid.Columns.Add(column); }
but Its displaying as hierarchical and I want a flat grid....
What am I doing wrong ?
Hi,
Correct, you would need to use an UnboundColumn as opposed to a TemplateColumn, as a TemplateColumn requires you to be bound to your Underlying data.
Btw, if you are always just displaying text, you can avoid creating a DataTemplate dynamically, and use the ValueConverter and ValueConverterParameter properties off the UnboundColumn instead.
By doing this, you'll also get sorting and GroupBy capabilities for free.
The value that will get passed into your converter, will be your row object, and i you set the Parameter property to your key, you'll be able to return something like:
return ((Row)value).Cells[(string)parameter];
from the convert method of your IValueConverter.
Now, you're seeing the Hierarchy, b/c you have AutoGenerateColumns set to true. So we're creating a ColumnLayout for your Cells collection, as its a public property. So, set the property to false, and your grid will remain flat.
Hope this helps,
-SteveZ
I have tried setting AutoGenerate to false, I then get 3 columns and 10 rows but no data.
As for the DataTemplate, I need textboxes so I can edit the values and soon I'll be adding combobox templates and some other controls. So will I have to implement sorting on my own or something? Plus I want TwoWay Binding Enabled