I am in the process of making a application for sending SOAP requests. Each request has a set of arguments or a lack of. Some arguments are numbers 0 to 100 or similar, some arguments can only be “Enabled” or “Disabled”, and some arguments are simply put to be a string of anykind.
The application will have you select a “Action” and this action will pull the arguments needed for the user. I want a DataGridView to show in column 1 the Argument Name and column 2 should be the value for the Argument.
However, in a goal to make this look nice, I wanted to see if there is a way to have some Combobox cells for the arguments that can only take specific values, and Textbox cells for the arguments that are meant to be a simple string.
I have tried including a variable in my argument object to define what kind of cell that row should be, then used CellFormatting (event) to catch when the cell is being drawn or made and format it with a specific type of cell. However, when I do this I get an error that seems like when it goes to paint the cell it throws a
An unhandled exception of type ‘System.NullReferenceException’ occurred in System.Windows.Forms.dll
Object reference not set to an instance of an object.
Below is my code
My datagrid has a source that looks like List<SOAPActionDataGridArgument> DataGridArgs
private void ArgumentDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == 1)
{
if (ArgumentDataGridView.Rows[e.RowIndex].DataBoundItem is SOAPActionDataGridArgument item && item != null)
{
DataGridViewCell cell = ArgumentDataGridView[e.ColumnIndex, e.RowIndex];
if (cell != null)
{
switch (item.ControlType)
{
case "Combo1":
if (!(cell is DataGridViewComboBoxCell))
{
var comboCell = new DataGridViewComboBoxCell();
if (item.Variable?.AllowedValues != null)
{
comboCell.DataSource = item.Variable.AllowedValues;
ArgumentDataGridView[e.ColumnIndex, e.RowIndex] = comboCell;
}
}
break;
case "Combo2":
if (!(cell is DataGridViewComboBoxCell))
{
var comboCell = new DataGridViewComboBoxCell();
if (item.Variable?.AllowedValueRange != null)
{
int min = item.Variable.AllowedValueRange.Minimum;
int max = item.Variable.AllowedValueRange.Maximum;
comboCell.DataSource = Enumerable.Range(min, max - min + 1).Select(i => i.ToString()).ToArray();
ArgumentDataGridView[e.ColumnIndex, e.RowIndex] = comboCell;
}
}
break;
default:
if (!(cell is DataGridViewTextBoxCell))
{
ArgumentDataGridView[e.ColumnIndex, e.RowIndex] = new DataGridViewTextBoxCell();
}
break;
}
}
}
}
}
My Objects being used (Models) whatever u wanna call it.
public class SOAPActionObject
{
public string Name { get; set; }
public List<SOAPActionArgument>? Arguments { get; set; }
public override string ToString()
{
return this.Name;
}
}
public class SOAPActionArgument
{
public string Name { get; set; }
public string Direction { get; set; }
public string RelatedStateVariable { get; set; }
public override string ToString()
{
return this.Name;
}
}
public class SOAPActionDataGridArgument
{
public SOAPActionArgument Argument { get; set; }
public string Value { get; set; }
public string ControlType { get; set; }
public SOAPActionStateVariable Variable { get; set; }
public SOAPActionDataGridArgument(SOAPActionArgument argument)
{
Argument = argument;
Value = "";
ControlType = "Text"; //Default
}
public SOAPActionDataGridArgument(SOAPActionArgument argument, string controlType, SOAPActionStateVariable variable)
{
Argument = argument;
Value = "";
ControlType = controlType;
Variable = variable;
}
}
public class SOAPActionStateVariable
{
public string Name { get; set; }
public string DataType { get; set; }
public ValueRange? AllowedValueRange { get; set; }
public List<string>? AllowedValues { get; set; }
}
public class ValueRange
{
public int Minimum { get; set; }
public int Maximum { get; set; }
}