/ / Przesyłanie obiektu jako ObservableCollection <object> - c #, .net, observablecollection

Przesyłanie obiektu jako ObservableCollection <object> - c #, .net, observablecollection

Próbuję napisać metodę, która pobiera wszystkie ObservableCollections w viewModel i rzuca każdy jako ObservableCollection<object>. Korzystając z refleksji, udało mi się uzyskać każdy z nich ObservableCollection<T> jako obiekt, ale mam trudności z rzuceniem tego obiektu na obiekt ObservableCollection<object>. Oto mój kod do tej pory:

var props = viewModel.GetType().GetProperties();

Type t = viewModel.GetType();

foreach (var prop in props)
{
if (prop.PropertyType.Name == "ObservableCollection`1")
{
Type type = prop.PropertyType;
var property = (t.GetProperty(prop.Name)).GetValue(viewModel);

// cast property as an ObservableCollection<object>
}
}

Czy ktoś wie, jak powinienem postępować?

Odpowiedzi:

2 dla odpowiedzi № 1

Porównywanie nazwy typu z ciągiem jest złym pomysłem. Aby stwierdzić, że jest ObservableCollectionmożesz użyć:

if (prop.PropertyType.IsGenericType &&
prop.PropertyType.GetGenericTypeDefinition() == typeof(ObservableCollection<>))

Wartość może zostać wyodrębniona i przekształcona jako taka:

foreach (var prop in viewModel.GetType().GetProperties())
{
if (prop.PropertyType.IsGenericType &&
prop.PropertyType.GetGenericTypeDefinition() == typeof(ObservableCollection<>))
{
var values = (IEnumerable)prop.GetValue(viewModel);

// cast property as an ObservableCollection<object>
var collection = new ObservableCollection<object>(values.OfType<object>());
}
}

Jeśli chcesz je połączyć w jedną kolekcję, możesz to zrobić:

var values = viewModel.GetType().GetProperties()
.Where(p => p.PropertyType.IsGenericType)
.Where(p => p.PropertyType.GetGenericTypeDefinition() == typeof(ObservableCollection<>))
.Select(p => (IEnumerable)p.GetValue(viewModel))
.SelectMany(e => e.OfType<object>());
var collection = new ObservableCollection<object>(values);

1 dla odpowiedzi nr 2

Odpowiedz na to pytanie tutaj: https://stackoverflow.com/a/1198760/3179310

Ale żeby wyjaśnić twoją sprawę:

if (prop.PropertyType.Name == "ObservableCollection`1")
{
Type type = prop.PropertyType;
var property = (t.GetProperty(prop.Name)).GetValue(viewModel);

// cast property as an ObservableCollection<object>
var col = new ObservalbeCollection<object>(property);
// if the example above fails you need to cast the property
// from "object" to an ObservableCollection<T> and then execute the code above
// to make it clear:
var mecol = new ObservableCollection<object>();
ICollection obscol = (ICollection)property;
for(int i = 0; i < obscol.Count; i++)
{
mecol.Add((object)obscol[i]);
}
// the example above can throw some exceptions but it should work in most cases
}

0 dla odpowiedzi № 3

Możesz użyć Cast<T>() metoda rozszerzenia, ale nie zapomnij, używając tegoMetoda (poniżej) spowoduje utworzenie nowej instancji, więc zdarzenia z oryginału nie działają. Jeśli nadal chcesz otrzymywać zdarzenia, powinieneś utworzyć wokół niego opakowanie.

var prop = viewModel.GetType("ObservableCollection`1");

var type = prop.PropertyType;
var propertyValue = (t.GetProperty(prop.Name)).GetValue(viewModel);

// cast property as an ObservableCollection<object>
var myCollection = new ObservableCollection<object>(
((ICollection)propertyValue).Cast<object>());

}