Reputation: 3038
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
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
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
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
Reputation: 11025
You can have an interface for the type and have your runtime types implement that interface.
Upvotes: 0
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