Reputation: 2826
I have an endpoint that returns an array of objects. I want to populate a DevExpress GridControl by making the keys of the object the columns and populating the rows with each objects corresponding value. The issue is that the gridcontrol only populates when I explicitly define what the keys of the json object is like this:
foreach(dynamic item in json){
report.Add(new
{
AccountID = item["AccountID"],
AccountTypeID = item["AccountTypeID"],
PrefixID = item["PrefixID"],
SuffixID = item["SuffixID"],
GenderID = item["GenderID"],
PrimaryContactID = item["PrimaryContactID"]
});
}
I don't want to hard code this because the array that is returned from my endpoint has different object structures returned. This is what I have so far, it gets the properties of my dynamic object and makes them the column names. It works in creating the column names but the rows are all empty.
public GridView()
{
InitializeComponent();
DevExpress.Mobile.Forms.Init();
PopulateGridView();
}
public async void PopulateGridView()
{
dynamic json = await model.GetItemAsync();
var report = new List<object>();
var custom = new Dictionary<string, string>();
foreach(dynamic item in json){
report.Add(item);
}
grid.ItemsSource = report;
foreach (JProperty x in (JToken)json[0])
{
TextColumn current = new TextColumn();
current.FieldName = x.Name;
grid.Columns.Add(current);
}
}
Here's what that looks like
Upvotes: 0
Views: 1806
Reputation: 2826
So I figured it out, what I did was create a DataTable. I took one object from the array and got all its properties to create the data tables column's and then created a function AddRow to add a row to the DataTable and did a foreach on all the objects in the same dynamic manner.
public DataTable dataTable { get; set; }
public GridView(dynamic obj)
{
InitializeComponent();
DevExpress.Mobile.Forms.Init();
dataTable = new DataTable();
PopulateGridView();
}
public async void PopulateGridView()
{
dynamic json = await model.GetItemAsync();
if(json == null){
await Navigation.PopToRootAsync();
}
AddColumns(json[0]);
foreach (dynamic item in json)
{
AddRow(item);
}
grid.ItemsSource = dataTable;
}
void AddColumns(dynamic obj)
{
foreach (JProperty x in (JToken)obj)
{
dataTable.Columns.Add(x.Name, typeof(string));
}
}
void AddRow(dynamic obj)
{
DataRow row = dataTable.NewRow();
foreach (JProperty x in (JToken)obj)
{
row[x.Name] = x.Value;
}
dataTable.Rows.Add(row);
}
Upvotes: 1
Reputation: 1690
If all dynamic objects in the sequence have the uniform structure, create a custom collection class implementing the ITypedList interface.
In the ITypedList.GetItemPropertis method, retrieve all available property names from the first object in the collection, and return the collection of custom property descriptors. The custom property descriptor should can read/write a value from/to the dynamic object given a property name.
The Grid will use property descriptors to access values in the dynamic object. This solution will work, since all data bound components natively support ITypedList collections.
Upvotes: 0