In Winform application I have a class with 2 properties and I want the user to be able to choose the type of those properties.
This is what I made so far:
Class with the properties:
static public class DataGridColumnData
{
public static object SearchColumn { get; set; }
public static object ResultColumn { get; set; }
}
And the user can choose the type of the properties using a Combobox with DropDownList Style which has values like
System.String
System.Double
System.Int32
System.Boolean
System.DateTime
Is there a way to make those properties to be types the ones that user chooses?
You can make your class generic:
static public class DataGridColumnData<T>
{
public static T SearchColumn { get; set; }
public static T ResultColumn { get; set; }
}
Then, in your code, you can create a class of the desired type:
object myDataGridColumnData;
if (userSelection == "String") {
myDataGridColumnData = new DataGridColumnData<string>();
} else if (userSelection == "Double") {
myDataGridColumnData = new DataGridColumnData<double>();
} ...
Note that, technically, DataGridColumnData<string>
is a completely different type than DataGridColumnData<int>
, so object
is the only common supertype. Thus, to be able to access the values of myDataGridColumnData
in code, you might need to use a dynamic
variable or (prefered) use some common interface or base class that returns the values typed as objects.
There are ways to make the properties strongly typed in runtime using generics, but I am not sure how useful it is. Here is a solution either way:
Create an interface that is not strongly typed to facilitate interaction with the object:
public interface IDataGridColumnData
{
object SearchColumnAsObject { get; set; }
object ResultColumnAsObject { get; set; }
}
Create generic class that allows for the creation of strongly typed versions at runtime (and in code as well, of course), and that implements the interface:
public class DataGridColumnData<TSearch, TResult> : IDataGridColumnData
{
public TSearch SearchColumn { get; set; }
public static TResult ResultColumn { get; set; }
public object SearchColumnAsObject
{
get { return SearchColumn; }
set { SearchColumn = (TSearch)value; }
}
public object ResultColumnAsObject
{
get { return ResultColumn; }
set { ResultColumn = (TResult)value; }
}
}
Create a factory method that will manufacture strongly typed versions of the class, returning it as the object-typed interface:
private static IDataGridColumnData GetDataGridColumnData(
Type searchType, Type resultType)
{
var typedColumnDataType = typeof(DataGridColumnData<,>)
.MakeGenericType(new[] { searchType, resultType });
return (IDataGridColumnData)Activator.CreateInstance(typedColumnDataType);
}
...and put it to use:
IDataGridColumnData instance = GetDataGridColumnData(
Type.GetType("System.Int32"),
Type.GetType("System.String"));
// use the properties
instance.SearchColumnAsObject = 42; // works well
instance.SearchColumnAsObject = "42"; // throws exception
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With