I've been trying to create a new base class for a Windows Forms form. I want to have this base class go through all the tableadapters it has on it and update their connection strings without anyone adding any code to the form. They just put the tableadapters on the form and don't worry about the connection string settings as it's all handled in the base class.
The problem is my reflection code can find the property fine, but it can't set it. How can I fix it?
Below is the code:
public class cFormWS : Form
{
public string ConnectionStringToUse { get; set; }
public cFormWS()
{
Load += cFormWS_Load;
}
void cFormWS_Load(object sender, EventArgs e)
{
InitiliseTableAdapters();
}
private void InitiliseTableAdapters()
{
var ListOfComponents = EnumerateComponents();
foreach (var ItemComp in ListOfComponents)
{
if (ItemComp.ToString().ToLower().EndsWith("tableadapter"))
{
var ItemCompProps = ItemComp.GetType().GetRuntimeProperties();
var TASQLConnection =
ItemCompProps.FirstOrDefault(
w => w.PropertyType == typeof(System.Data.SqlClient.SqlConnection));
if (TASQLConnection != null)
{
var property = typeof(System.Data.SqlClient.SqlConnection).GetProperty("ConnectionString");
// How do I set the value?
string value = "some new connection string";
var ConvertedProperty = Convert.ChangeType(value, property.PropertyType);
// I tried seting a value. It is not working:
// "object does not match target type"
property.SetValue(TASQLConnection, ConvertedProperty, null);
//// I tried using a method. It is not working:
//// "object does not match target type"
//var m = property.SetMethod;
//ParameterInfo[] parameters = m.GetParameters();
//m.Invoke(m, parameters); // m.Invoke(this, parameters); // m.Invoke(ItemComp, parameters);
}
}
}
}
private IEnumerable<Component> EnumerateComponents()
{
return from field in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
where typeof(Component).IsAssignableFrom(field.FieldType)
let component = (Component)field.GetValue(this)
where component != null
select component;
}
When you do SetValue
, you need to pass in the object that you wish to set the property on.
ItemComp
: This is incorrect, since the ConnectionString
is a property of the SqlConnection
which is a property of ItemComp
TASqlConnection
. However, this is not the object, but a PropertyInfo
based of the objectItemComp
object and pass that in:property.SetValue(TASQLConnection.GetValue(ItemComp), ConvertedProperty, null);
ORIGINAL (INCORRECT) ANSWER:
You're trying to set a ConnectionString
property of ItemComp
. The ConnectionString is not a property of the TableAdapter
, but of the SqlConnection
(which is a property of the TableAdapter
).
The correct way of setting the property would be this:
property.SetValue(TASQLConnection, ConvertedProperty, null);