/// <summary>Get a list of column names for table.</summary> public string[] ColumnNames(string tableName) { string sql = "SELECT * FROM " + tableName + " LIMIT 1"; DataTable data = RunQuery(sql); return(DataTableUtilities.GetColumnNames(data)); }
public void TestArrayRangeWithStartAndEndSpecification() { var mod = new MockModel() { Z = new double[] { 1, 2, 3 } }; simulation.Children.Add(mod); simulation.Children.Remove(storage); var datastore = new DataStore(); simulation.Children.Add(datastore); Utilities.InitialiseModel(simulation); report.VariableNames = new string[] { "[MockModel].Z[2:3]" }; Assert.IsNull(runner.Run()); datastore.Writer.Stop(); var data = datastore.Reader.GetData("Report"); var columnNames = DataTableUtilities.GetColumnNames(data); Assert.IsFalse(columnNames.Contains("MockModel.Z(0)")); Assert.IsFalse(columnNames.Contains("MockModel.Z(1)")); Assert.IsTrue(columnNames.Contains("MockModel.Z(2)")); Assert.IsTrue(columnNames.Contains("MockModel.Z(3)")); Assert.IsFalse(columnNames.Contains("MockModel.Z(4)")); Assert.AreEqual(DataTableUtilities.GetColumnAsDoubles(data, "MockModel.Z(2)"), new double[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }); Assert.AreEqual(DataTableUtilities.GetColumnAsDoubles(data, "MockModel.Z(3)"), new double[] { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }); }
/// <summary>Get data to show in grid.</summary> /// <param name="startRowIndex">The row index to start getting data from.</param> private DataPage GetData(int startRowIndex) { PagingStart?.Invoke(this, new EventArgs()); var newData = dataStore.GetData(tableName, checkpointName, simulationNames, columnNames, GetRollingCursorRowFilter(startRowIndex, pageSize)); // Remove unwanted columns from data table. foreach (string columnName in DataTableUtilities.GetColumnNames(newData)) { if (!columnNames.Contains(columnName)) { newData.Columns.Remove(columnName); } } var newPage = new DataPage(newData, startRowIndex); dataPages.Add(newPage); PagingEnd?.Invoke(this, new EventArgs()); return(newPage); }
/// <summary>Get a list of database fieldnames. /// Returns the names associated with the first table name in the property list /// </summary> /// <returns>A list of fieldnames.</returns> private string[] GetFieldNames() { string[] fieldNames = null; for (int i = 0; i < this.properties.Count; i++) { if (this.properties[i].Display.Type == DisplayType.TableName) { IGridCell cell = this.grid.GetCell(1, i); if (cell.Value != null && cell.Value.ToString() != string.Empty) { string tableName = cell.Value.ToString(); DataTable data = null; if (storage.TableNames.Contains(tableName)) { data = this.storage.RunQuery("SELECT * FROM " + tableName + " LIMIT 1"); } if (data != null) { fieldNames = DataTableUtilities.GetColumnNames(data); } } } } return(fieldNames); }
/// <summary> /// The main run method called to fill tables in the specified DataStore. /// </summary> /// <param name="dataStore">The DataStore to work with</param> public void Run(IStorageReader dataStore) { dataStore.DeleteDataInTable(this.Name); DataTable statsData = new DataTable(); statsData.Columns.Add("SimulationName", typeof(string)); statsData.Columns.Add("VariableName", typeof(string)); statsData.Columns.Add("n", typeof(string)); statsData.Columns.Add("residual", typeof(double)); statsData.Columns.Add("R^2", typeof(double)); statsData.Columns.Add("RMSD", typeof(double)); statsData.Columns.Add("%", typeof(double)); statsData.Columns.Add("MSD", typeof(double)); statsData.Columns.Add("SB", typeof(double)); statsData.Columns.Add("SDSD", typeof(double)); statsData.Columns.Add("LCS", typeof(double)); DataTable simulationData = dataStore.GetData(this.TableName); if (simulationData != null) { DataView view = new DataView(simulationData); string[] columnNames = DataTableUtilities.GetColumnNames(simulationData); foreach (string observedColumnName in columnNames) { if (observedColumnName.StartsWith("Observed.")) { string predictedColumnName = observedColumnName.Replace("Observed.", "Predicted."); if (simulationData.Columns.Contains(predictedColumnName)) { DataColumn predictedColumn = simulationData.Columns[predictedColumnName]; DataColumn observedColumn = simulationData.Columns[observedColumnName]; if (predictedColumn.DataType == typeof(double) && observedColumn.DataType == typeof(double)) { // Calculate stats for each simulation and store them in a rows in our stats table. string[] simulationNames = dataStore.SimulationNames; foreach (string simulationName in simulationNames) { string seriesName = simulationName; view.RowFilter = "SimulationName = '" + simulationName + "'"; CalcStatsRow(view, observedColumnName, predictedColumnName, seriesName, statsData); } // Calculate stats for all simulations and store in a row of the stats table. string overallSeriesName = "Combined " + observedColumnName.Replace("Observed.", ""); view.RowFilter = null; CalcStatsRow(view, observedColumnName, predictedColumnName, overallSeriesName, statsData); } } } } // Write the stats data to the DataStore statsData.TableName = this.Name; dataStore.WriteTable(statsData); } }
/// <summary>Get a list of database fieldnames. /// Returns the names associated with the first table name in the property list /// </summary> /// <returns>A list of fieldnames.</returns> private List <string> GetFieldNames() { List <string> fieldNames = null; for (int i = 0; i < properties.Count; i++) { if (properties[i].Display != null && properties[i].Display.Type == DisplayType.TableName) { IGridCell cell = grid.GetCell(1, i); if (cell.Value != null && cell.Value.ToString() != string.Empty) { string tableName = cell.Value.ToString(); DataTable data = null; if (storage.TableNames.Contains(tableName)) { data = storage.RunQuery("SELECT * FROM " + tableName + " LIMIT 1"); } if (data != null) { fieldNames = DataTableUtilities.GetColumnNames(data).ToList(); if (fieldNames.Contains("SimulationID")) { fieldNames.Add("SimulationName"); } } } } } return(fieldNames); }
/// <summary> /// Return a list of valid fieldnames. /// </summary> /// <param name="graph">The parent graph</param> /// <returns>The array of field names</returns> public string[] ValidFieldNames(Graph graph) { if (graph.DataStore != null && this.TableName != null && this.TableName != string.Empty) { List <string> names = new List <string>(); names.AddRange(DataTableUtilities.GetColumnNames(graph.DataStore.GetData("*", this.TableName))); return(names.ToArray()); } return(null); }
/// <summary>Populates the field names in the view.</summary> /// <param name="dataStore">The data store.</param> private void PopulateFieldNames(DataStore dataStore) { if (this.seriesView.DataSource != null) { DataTable data = dataStore.RunQuery("SELECT * FROM " + this.seriesView.DataSource + " LIMIT 1"); if (data != null) { this.seriesView.SetFieldNames(DataTableUtilities.GetColumnNames(data)); } } }
/// <summary> /// Populate our view. /// </summary> private void PopulateView() { View.TableNames = DataStore.TableNames; View.PredictedTableName = PredictedObserved.PredictedTableName; View.ObservedTableName = PredictedObserved.ObservedTableName; DataTable table = DataStore.GetData("*", PredictedObserved.ObservedTableName); if (table != null) { View.FieldNames = DataTableUtilities.GetColumnNames(table); View.FieldName = PredictedObserved.FieldNameUsedForMatch; } }
/// <summary>Main run method for performing our calculations and storing data.</summary> public void Run() { if (dataStore?.Writer != null) { using (var connection = new SqlConnection(ConnectionString)) { connection.Open(); foreach (var tableName in TableNames) { if (dataStore.Reader.TableNames.Contains(tableName)) { var data = dataStore.Reader.GetData(tableName); data.TableName = tableName; if (data != null) { // Strip out unwanted columns. data.Columns.Remove("CheckpointName"); data.Columns.Remove("CheckpointID"); data.Columns.Remove("SimulationID"); CreateTableIfNotExists(connection, data); var columnNames = DataTableUtilities.GetColumnNames(data).ToList(); var sql = CreateInsertSQL(tableName, columnNames); using (SqlCommand cmd = new SqlCommand(sql, connection)) { cmd.Prepare(); foreach (DataRow row in data.Rows) { BindParametersAndRunQuery(cmd, columnNames, row.ItemArray); } } } } } } } }
/// <summary>Get a list of database fieldnames. /// Returns the names associated with the first table name in the property list /// </summary> /// <returns>A list of fieldnames.</returns> private string[] GetFieldNames() { string[] fieldNames = null; for (int i = 0; i < this.properties.Count; i++) { if (this.properties[i].DisplayType == DisplayAttribute.DisplayTypeEnum.TableName) { DataStore dataStore = new DataStore(this.model); IGridCell cell = this.grid.GetCell(1, i); if (cell.Value != null && cell.Value.ToString() != string.Empty) { DataTable data = dataStore.RunQuery("SELECT * FROM " + cell.Value.ToString() + " LIMIT 1"); if (data != null) { fieldNames = DataTableUtilities.GetColumnNames(data); } } dataStore.Disconnect(); } } return(fieldNames); }
public List <string> ColumnNames(string tableName) { return(DataTableUtilities.GetColumnNames(data).ToList()); }
/// <summary> /// Invoked when the view wants context items. /// </summary> /// <param name="sender">Event sender</param> /// <param name="e">Event arguments</param> public void OnContextItemsNeeded(object sender, NeedContextItemsArgs e) { if (e.ObjectName.Trim() == "Simulation") { e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = "All" }); foreach (string simulationName in this.dataStore.SimulationNames) { e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = simulationName }); } } else if (e.ObjectName.Trim() == "Test") { string tableName = this.view.TableName; if (tableName != null) { DataTable data = this.dataStore.GetData("*", tableName); if (data != null) { foreach (string columnName in DataTableUtilities.GetColumnNames(data)) { e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = columnName }); } } } } else { string simulationName = this.GetWordFromLine(this.view.Editor.CurrentLineNumber, "Simulation:", false); string testName = this.GetWordFromLine(this.view.Editor.CurrentLineNumber, "Test:", false); if (simulationName != null && testName != null) { e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = "=" }); e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = "<" }); e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = ">" }); e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = "AllPositive" }); e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = "between" }); e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = "mean=" }); e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = "tolerance=" }); e.AllItems.Add(new NeedContextItemsArgs.ContextItem() { Name = "CompareToInput=" }); } } }
/// <summary> /// Paint the visual elements (colour, line and marker) of all simulation / zone pairs. /// </summary> /// <param name="factors">The simulation/zone pairs to change</param> /// <param name="storage">Storage reader</param> /// <param name="baseData">Base data</param> private List <SeriesDefinition> ConvertToSeriesDefinitions(List <ISimulationGeneratorFactors> factors, IStorageReader storage, DataTable baseData) { // Create an appropriate painter object SimulationZonePainter.IPainter painter; if (FactorToVaryColours != null) { if (FactorToVaryLines == FactorToVaryColours) { painter = new SimulationZonePainter.SequentialPainterTwoFactors() { FactorName = FactorToVaryColours, MaximumIndex1 = ColourUtilities.Colours.Length, MaximumIndex2 = Enum.GetValues(typeof(LineType)).Length - 1, // minus 1 to avoid None type Setter1 = VisualElements.SetColour, Setter2 = VisualElements.SetLineType } } ; else if (FactorToVaryMarkers == FactorToVaryColours) { painter = new SimulationZonePainter.SequentialPainterTwoFactors() { FactorName = FactorToVaryColours, MaximumIndex1 = ColourUtilities.Colours.Length, MaximumIndex2 = Enum.GetValues(typeof(MarkerType)).Length - 1,// minus 1 to avoid None type Setter1 = VisualElements.SetColour, Setter2 = VisualElements.SetMarker } } ; else if (FactorToVaryLines != null) { painter = new SimulationZonePainter.DualPainter() { FactorName1 = FactorToVaryColours, FactorName2 = FactorToVaryLines, MaximumIndex1 = ColourUtilities.Colours.Length, MaximumIndex2 = Enum.GetValues(typeof(LineType)).Length - 1, // minus 1 to avoid None type Setter1 = VisualElements.SetColour, Setter2 = VisualElements.SetLineType } } ; else if (FactorToVaryMarkers != null) { painter = new SimulationZonePainter.DualPainter() { FactorName1 = FactorToVaryColours, FactorName2 = FactorToVaryMarkers, MaximumIndex1 = ColourUtilities.Colours.Length, MaximumIndex2 = Enum.GetValues(typeof(MarkerType)).Length - 1,// minus 1 to avoid None type Setter1 = VisualElements.SetColour, Setter2 = VisualElements.SetMarker } } ; else { painter = new SimulationZonePainter.SequentialPainter() { FactorName = FactorToVaryColours, MaximumIndex = ColourUtilities.Colours.Length, Setter = VisualElements.SetColour } }; } else if (FactorToVaryLines != null) { painter = new SimulationZonePainter.SequentialPainter() { FactorName = FactorToVaryLines, MaximumIndex = Enum.GetValues(typeof(LineType)).Length - 1, // minus 1 to avoid None type Setter = VisualElements.SetLineType }; } else if (FactorToVaryMarkers != null) { painter = new SimulationZonePainter.SequentialPainter() { FactorName = FactorToVaryMarkers, MaximumIndex = Enum.GetValues(typeof(MarkerType)).Length - 1,// minus 1 to avoid None type Setter = VisualElements.SetMarker }; } else { painter = new SimulationZonePainter.DefaultPainter() { Colour = Colour, LineType = Line, MarkerType = Marker } }; List <SeriesDefinition> definitions = new List <SeriesDefinition>(); // Apply the painter to all simulation zone objects. foreach (ISimulationGeneratorFactors factor in factors) { VisualElements visualElement = new VisualElements(); visualElement.colour = Colour; visualElement.Line = Line; visualElement.LineThickness = LineThickness; visualElement.Marker = Marker; visualElement.MarkerSize = MarkerSize; painter.PaintSimulationZone(factor, visualElement); SeriesDefinition seriesDefinition = new Models.Graph.SeriesDefinition(); seriesDefinition.type = Type; seriesDefinition.marker = visualElement.Marker; seriesDefinition.line = visualElement.Line; seriesDefinition.markerSize = visualElement.MarkerSize; seriesDefinition.lineThickness = visualElement.LineThickness; seriesDefinition.colour = visualElement.colour; seriesDefinition.xFieldName = XFieldName; seriesDefinition.yFieldName = YFieldName; seriesDefinition.xAxis = XAxis; seriesDefinition.yAxis = YAxis; seriesDefinition.xFieldUnits = storage.GetUnits(TableName, XFieldName); seriesDefinition.yFieldUnits = storage.GetUnits(TableName, YFieldName); seriesDefinition.showInLegend = ShowInLegend; factor.Factors.ForEach(f => seriesDefinition.title += f.Value); if (IncludeSeriesNameInLegend) { seriesDefinition.title += ": " + Name; } if (Checkpoint != "Current") { seriesDefinition.title += " (" + Checkpoint + ")"; } DataView data = new DataView(baseData); try { data.RowFilter = CreateRowFilter(storage, new ISimulationGeneratorFactors[] { factor }, DataTableUtilities.GetColumnNames(baseData)); } catch { } if (data.Count > 0) { seriesDefinition.data = data.ToTable(); seriesDefinition.x = GetDataFromTable(seriesDefinition.data, XFieldName); seriesDefinition.y = GetDataFromTable(seriesDefinition.data, YFieldName); seriesDefinition.x2 = GetDataFromTable(seriesDefinition.data, X2FieldName); seriesDefinition.y2 = GetDataFromTable(seriesDefinition.data, Y2FieldName); seriesDefinition.error = GetErrorDataFromTable(seriesDefinition.data, YFieldName); if (Cumulative) { seriesDefinition.y = MathUtilities.Cumulative(seriesDefinition.y as IEnumerable <double>); } if (CumulativeX) { seriesDefinition.x = MathUtilities.Cumulative(seriesDefinition.x as IEnumerable <double>); } } definitions.Add(seriesDefinition); } return(definitions); }
/// <summary> /// Populate the views series editor with the current selected series. /// </summary> private void PopulateSeriesEditor() { int seriesIndex = Array.IndexOf(this.seriesView.SeriesNames, this.seriesView.SelectedSeriesName); if (seriesIndex != -1 && seriesIndex < this.graph.Series.Count) { if (!InPopulateSeriesEditor) { InPopulateSeriesEditor = true; DisconnectViewEvents(); Series series = this.graph.Series[seriesIndex]; series.Title = this.seriesView.SeriesNames[seriesIndex]; this.seriesView.EditorVisible = true; this.seriesView.SeriesEditor.OverallRegression = this.graph.ShowRegressionLine; if (series.Type == Series.SeriesType.Line) { series.Type = Series.SeriesType.Scatter; } this.seriesView.SeriesEditor.SeriesType = series.Type.ToString(); this.seriesView.SeriesEditor.SeriesLineType = series.Line.ToString(); this.seriesView.SeriesEditor.SeriesMarkerType = series.Marker.ToString(); this.seriesView.SeriesEditor.Colour = series.Colour; this.seriesView.SeriesEditor.Regression = series.ShowRegressionLine; this.seriesView.SeriesEditor.XOnTop = series.XAxis == Axis.AxisType.Top; this.seriesView.SeriesEditor.YOnRight = series.YAxis == Axis.AxisType.Right; this.seriesView.SeriesEditor.ShowInLegend = series.ShowInLegend; this.seriesView.SeriesEditor.Cumulative = series.Cumulative; // Populate the editor with a list of data sources. List <string> dataSources = new List <string>(); if (dataStore != null) { foreach (string tableName in dataStore.TableNames) { if (tableName != "Messages" && tableName != "InitialConditions") { dataSources.Add(tableName); } } dataSources.Sort(); } this.seriesView.SeriesEditor.SetDataSources(dataSources.ToArray()); if (series.X != null) { this.seriesView.SeriesEditor.DataSource = series.X.TableName; } else if (dataSources.Count > 0) { this.seriesView.SeriesEditor.DataSource = dataSources[0]; } if (this.seriesView.SeriesEditor.DataSource != null) { DataTable data = dataStore.GetData("*", this.seriesView.SeriesEditor.DataSource); if (data != null) { this.seriesView.SeriesEditor.SetFieldNames(DataTableUtilities.GetColumnNames(data)); } } if (series.X != null) { this.seriesView.SeriesEditor.X = series.X.FieldName; } else { this.seriesView.SeriesEditor.X = null; } if (series.Y != null) { this.seriesView.SeriesEditor.Y = series.Y.FieldName; } else { this.seriesView.SeriesEditor.Y = null; } if (series.X2 != null) { this.seriesView.SeriesEditor.X2 = series.X2.FieldName; } else { this.seriesView.SeriesEditor.X2 = null; } if (series.Y2 != null) { this.seriesView.SeriesEditor.Y2 = series.Y2.FieldName; } else { this.seriesView.SeriesEditor.Y2 = null; } this.seriesView.SeriesEditor.ShowX2Y2(series.Type == Series.SeriesType.Area); ConnectViewEvents(); InPopulateSeriesEditor = false; } } else { this.seriesView.EditorVisible = false; } }
/// <summary>Reads all data from the specified reader.</summary> /// <param name="data">Data to read from.</param> /// <param name="simulationDescriptions">Complete list of simulation descriptions.</param> /// <param name="reader">Data store reader.</param> public void ReadData(DataTable data, List <SimulationDescription> simulationDescriptions, IStorageReader reader) { if (X != null && Y != null) { return; } if (Series.TableName == null) { GetDataFromModels(); } else { var fieldsThatExist = DataTableUtilities.GetColumnNames(data).ToList(); // If we have descriptors, then use them to filter the data for this series. List <string> simulationNameFilter = new List <string>();; IEnumerable <SimulationDescription> simulationNamesWithDescriptors = new List <SimulationDescription>(); if (Descriptors != null) { foreach (var descriptor in Descriptors) { if (!fieldsThatExist.Contains(descriptor.Name)) { if (simulationNamesWithDescriptors.Any()) { simulationNamesWithDescriptors = simulationNamesWithDescriptors.Where(s => s.HasDescriptor(descriptor)); } else { simulationNamesWithDescriptors = simulationDescriptions.Where(sim => sim.HasDescriptor(descriptor)); } } } if (simulationNamesWithDescriptors.Any()) { simulationNameFilter = simulationNamesWithDescriptors.Select(s => s.Name).ToList(); } // Incorporate our scope filter if we haven't limited filter to particular simulations. if (!simulationNameFilter.Any() && InScopeSimulationNames != null) { simulationNameFilter = new List <string>(InScopeSimulationNames); } } else if (InScopeSimulationNames != null) { simulationNameFilter = new List <string>(InScopeSimulationNames ?? Enumerable.Empty <string>()); } string filter = GetFilter(fieldsThatExist); if (simulationNameFilter.Any()) { var simulationIds = reader.ToSimulationIDs(simulationNameFilter); var simulationIdsCSV = StringUtilities.Build(simulationIds, ","); if (fieldsThatExist.Contains("SimulationID")) { filter = AddToFilter(filter, $"SimulationID in ({simulationIdsCSV})"); } } filter = filter?.Replace('\"', '\''); View = new DataView(data); View.RowFilter = filter; // Get the units for our x and y variables. XFieldUnits = reader.Units(Series.TableName, XFieldName); YFieldUnits = reader.Units(Series.TableName, YFieldName); // If data was found, populate our data (e.g. X and Y) properties. if (View?.Count > 0) { X = GetDataFromView(View, XFieldName); Y = GetDataFromView(View, YFieldName); X2 = GetDataFromView(View, X2FieldName); Y2 = GetDataFromView(View, Y2FieldName); XError = GetErrorDataFromView(View, XFieldName); YError = GetErrorDataFromView(View, YFieldName); if (Series.Cumulative) { Y = MathUtilities.Cumulative(Y as IEnumerable <double>); } if (Series.CumulativeX) { X = MathUtilities.Cumulative(X as IEnumerable <double>); } } } }
/// <summary> /// Format the grid. /// </summary> private void FormatGrid() { string[] fieldNames = null; for (int i = 0; i < this.properties.Count; i++) { IGridCell cell = this.grid.GetCell(1, i); if (this.properties[i].DisplayType == DisplayAttribute.DisplayTypeEnum.TableName) { DataStore dataStore = new DataStore(this.model); cell.EditorType = EditorTypeEnum.DropDown; cell.DropDownStrings = dataStore.TableNames; if (cell.Value != null && cell.Value.ToString() != string.Empty) { DataTable data = dataStore.RunQuery("SELECT * FROM " + cell.Value.ToString() + " LIMIT 1"); if (data != null) { fieldNames = DataTableUtilities.GetColumnNames(data); } } dataStore.Disconnect(); } else if (this.properties[i].DisplayType == DisplayAttribute.DisplayTypeEnum.CultivarName) { cell.EditorType = EditorTypeEnum.DropDown; ICrop crop = GetCrop(properties); if (crop != null) { cell.DropDownStrings = GetCultivarNames(crop); } } else if (this.properties[i].DisplayType == DisplayAttribute.DisplayTypeEnum.FileName) { cell.DropDownStrings = this.properties[i].Metadata; cell.EditorType = EditorTypeEnum.Button; } else if (this.properties[i].DisplayType == DisplayAttribute.DisplayTypeEnum.FieldName) { cell.EditorType = EditorTypeEnum.DropDown; if (fieldNames != null) { cell.DropDownStrings = fieldNames; } } else { object cellValue = this.properties[i].ValueWithArrayHandling; if (cellValue is DateTime) { cell.EditorType = EditorTypeEnum.DateTime; } else if (cellValue is bool) { cell.EditorType = EditorTypeEnum.Boolean; } else if (cellValue.GetType().IsEnum) { cell.EditorType = EditorTypeEnum.DropDown; cell.DropDownStrings = StringUtilities.EnumToStrings(cellValue); } else if (cellValue.GetType() == typeof(ICrop)) { cell.EditorType = EditorTypeEnum.DropDown; List <string> cropNames = new List <string>(); foreach (Model crop in Apsim.FindAll(this.model, typeof(ICrop))) { cropNames.Add(crop.Name); } cell.DropDownStrings = cropNames.ToArray(); } else if (this.properties[i].DataType == typeof(ICrop)) { List <string> plantNames = Apsim.FindAll(this.model, typeof(ICrop)).Select(m => m.Name).ToList(); cell.EditorType = EditorTypeEnum.DropDown; cell.DropDownStrings = plantNames.ToArray(); } else { cell.EditorType = EditorTypeEnum.TextBox; } } } IGridColumn descriptionColumn = this.grid.GetColumn(0); descriptionColumn.Width = -1; descriptionColumn.ReadOnly = true; IGridColumn valueColumn = this.grid.GetColumn(1); valueColumn.Width = -1; }