mahboub_mo
mahboub_mo

Reputation: 3038

How to use the type that returned by GetType in ObservableCollection<T>?

I want to cast the ItemSource of a WPF dataGrid to an ObservableCollection,But i don't know the type of its elements,so i was thinking to get the type using this code:

 var returnedType = dg.ItemsSource.AsQueryable().ElementType;

And use the returnedType here:

var sourceCollection = (ObservableCollection<???>)dg.ItemsSource;

To be more clear i want to cast it into ObservableCollection because i need to use itsCollectionChanged.And i can't use generic types here because i want to use it in a customizad DataGrid.

Upvotes: 1

Views: 922

Answers (5)

Knaģis
Knaģis

Reputation: 21485

ObservableCollection<T> implements the INotifyCollectionChanged interface and the event you need is defined on this interface. So you can write the code like this:

var sourceCollection = (INotifyCollectionChanged)dg.ItemsSource;
sourceCollection.CollectionChanged += ... your delegate here ...

Upvotes: 4

sm_
sm_

Reputation: 2602

Although, its not clear what you need, and what would be generics of any use if you don't know the type or an abstraction of it at compile time. Here is a way :

var returnedType = dg.ItemsSource.AsQueryable().ElementType;
Type generic = typeof(ObservableCollection<>);    
Type specific = generic.MakeGenericType(typeof(returnedType));    
ConstructorInfo ci = specific.GetConstructor(Type.EmptyTypes);    
object o = ci.Invoke(new object[] { });

the object o is your ObservableCollection<returnedType >.

And if you need to invoke any methods of the ObservableCollections upon it, you are going to need reflection to do so.

Upvotes: 0

Rune FS
Rune FS

Reputation: 21742

A downcast is a compile time construct letting the compile know that you know more that the compile does about the runtime type of the object. If you don't know the type at compile time you can't use a cast.

However if you don't know the actual type you won't be able to do much with it later on anyways. How would you access a property of an object of an unknown type?

In general there'd be two different ways of handling issues with unknown types where they have some commonalities one would be the dynamic language runtime

dynamic sourceCollection = dg.ItemsSource;

You can use this if you know that all objects will have e.g. a Value property but that they do not share a common base type declaring that property.

sourceCollection.Value

would in that case be legal (and work as long as the constraint is not violated)

or maybe more often you'd be able to pass sourceCollection to a method that accepts an ObservableCollaction<T> as an argument

Alternatively you can use generics

public ObservableCollection<T> GetSourceCollection(DataGrid dg) {
    (ObservableCollection<T>)dg.ItemsSource
}

This only defers the issue of not knowing the type to somewhere else in your code but you should know the type of collection at some point and you will often be able to push the issue until that point.

Upvotes: 0

Victor Mukherjee
Victor Mukherjee

Reputation: 11025

You can have an interface for the type and have your runtime types implement that interface.

Upvotes: 0

Sean
Sean

Reputation: 62472

ObservableCollection<> is derived from Collection<>, so you can cast it to IList or ICollection and access the collection that way. However, you'll have to treat the items in the collection as object.

Upvotes: 0

Related Questions