Hi all,
I am working on a piece of code that should be able to display a set of data which is unknown on compile time: meaning I want to execute SQL statements, without knowing the model before execution.
Since the rows are in my case returned as object arrays (due to a generic transport model), I have to bind them at runtime.
This is the code I use for the moment:
List<UltraGridColumn> columns = new List<UltraGridColumn>(); int i = 0;
foreach (string entityField in actionTable.FieldDefinitions) {UltraGridColumn column = new UltraGridColumn(entityField, i++); column.Header.VisiblePosition = i;ultraGrid1.DisplayLayout.Bands[0].Columns.Add(column);}
this.ultraGrid1.DataSource = actionTable.Result; // this is an object array.
In the InitializeLayout event I try the following:
UltraGridColumn column = this.ultraGrid1.DisplayLayout.Bands[0].Columns["fieldName1"];
if (column.Editor == null){//execute some code}
Then at the line with the "if (column.Editor == null)" a NullReferenceException is thrown. Does anyone have a clue why?
There are a couple of issues here.
First, the Add method on the Columns collection is not intended to take a column object. If you look at the intellisense for ultraGrid1.DisplayLayout.Bands[0].Columns.Add, you will not see an overload that takes a Column object. There actually is an overload for this - which is why your code compiles, but you are not supposed to use that overload. It's only there for internal use for serialization purposes.
The grid columns are created based on the DataSource you assign to the grid. So you are adding some columns to the grid (which, as I said, you should not do), and then when you set the DataSource property on the grid, the entire layout of the grid (including all of the columns) are thrown away in favor of the data source's structure.
Does the object array you are binding to contain objects that are all the same type? If so, then I think the grid will pick up the type of the first item in the array and use the properties of that object as the columns in the grid. Although... I'm not sure this will work for a list of objects. The grid has no control over that, though, it's all up to the BindingManager class in DotNet.
So if this is not working and you are not getting any columns, you will have to use something else as the grid's DataSource. You could copy the data into a strongly-typed List<T> or BindingList<T>, for example. Or, you could copy the data into an UltraDataSource. Or... you could use the UltraDataSource as a sort've intermediary between the grid and the real data source in On-demand mode. There's a sample of this list technique in the WinGrid Samples Explorer called the Virtual Mode Sample.
Hi Mike,
Thanks for this useful suggestion. It works the way I want it now, so that is great. I use the CellDataRequested event to get the data from the List<object[]> to the grid.
Yet, another question pops up: Is there an event which occurs after databinding the grid. I had like to call the PerformAutoResizeColumns method after every time I bind to the object, but that does not seem possible.
Can you suggest any event?
Thanks,
Patrick