SetValue of indexed property in C # using Reflection

I have a class that has

ObservableCollection<int> 

as a property, and I'm trying to change the value inside this property of an instance of this class. Here is the code that I have that gets a TargetException:

 object[] index = null; var originalPropertyName = propertyName; if (propertyName.Contains("[") && propertyName.Contains("]")) { index = new object[1]; index[0] = Convert.ToInt32(propertyName.Split('[')[1].Split(']')[0]); propertyName = propertyName.Split('[')[0]; } PropertyInfo pi = item.GetType().GetProperty(propertyName); PropertyInfo opi = item.GetType().GetProperty(originalPropertyName); Type pType = index != null ? pi.PropertyType.GetGenericArguments()[0] : pi.PropertyType; if (pi != null) { object convertedValue = Convert.ChangeType(value, pType); if (index == null) { item.GetType().GetProperty(propertyName).SetValue(item, convertedValue, null); } else { //PropertyInfo ipi = pi.PropertyType.GetProperties().Single(p => p.GetIndexParameters().Length > 0); //var collection = pi.GetValue(item, index); //collection.GetType().GetProperty("Value").SetValue(collection, convertedValue, null); var _pi = pi.PropertyType.GetProperty("Item"); _pi.SetValue(pi, convertedValue, index); } } 

As the property propertyName is not shown above, but in the case of an indexed property, it begins its life as "IndexedProperty [10]", for example.

In the comments after this "else", you can see other things that I tried by reading a few other stackoverflow posts and in other forums on how to do this, but still failed. Any ideas?

Casting a property to an ObservableCollection is not possible because I want it to be dynamic.

The concept of everything is to have a DataGrid connected to the data, and have a paste that works correctly by updating the correct properties of each instance, whether the properties are indexed or not. Non-indexed properties work fine, but I can't get the ObservableCollection to work.

+8
reflection c #
source share
2 answers

A class with an ObservableCollection<int> as a property does not actually have an indexed property in the traditional sense of an indexer. It just has an unindexed property that has an index. Therefore, you need to use GetValue to start with (without specifying an index) and then extract the indexer from the result.

Basically, you need to remember that:

 foo.People[10] = new Person(); 

equivalent to:

 var people = foo.People; // Getter people[10] = new Person(); // Indexed setter 

It looks like you were next to this commented code:

 //var collection = pi.GetValue(item, index); //collection.GetType().GetProperty("Value").SetValue(collection, convertedValue, null); 

... but you applied the index at the wrong point. You want (I think the question is not very clear):

 var collection = pi.GetValue(item, null); collection.GetType() .GetProperty("Item") // Item is the normal name for an indexer .SetValue(collection, convertedValue, index); 
+11
source share

try this i'm not sure if it will work

 _pi.SetValue(pi, convertedValue, new object[] { (int) 0 }); //where 0 is the index in which you want to insert the value, in this case to index 0 
0
source share

All Articles