问题
I hope someone can help with this one. I've been trying to create a new base class for a WinForm. What I want to do is 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 I'm having is my reflection code can find the property fine but can't set it. Can someone help?
Below is code (updated)
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);
// tried seting value. not working "object does not match target type"
property.SetValue(TASQLConnection, ConvertedProperty, null);
//// tried using a method. 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;
}
回答1:
EDIT:
When you do SetValue
, you need to pass in the object that you wish to set the property on.
- In your first example code, you passed in
ItemComp
: This is incorrect, since theConnectionString
is a property of theSqlConnection
which is a property ofItemComp
- In your edited question (and my original answer) you pass in the
TASqlConnection
. However, this is not the object, but aPropertyInfo
based of the object - The correct way is to get the value from the
ItemComp
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);
来源:https://stackoverflow.com/questions/31048117/c-sharp-reflection-set-tableadapter-connectionstring