-2

Given an arbitrary ItemsControl, is it possible to get the type of the container objects which its ItemContainerGenerator creates/uses?

For example, given a ListBox, I'm trying to get the type ListBoxItem. For a TreeView, it would be TreeViewItem, etc.

I'm trying to find a generic solution for any ItemsControl (or more accurately, any control which utilizes an ItemContainerGenerator.)

I'm specifically looking for the Type, not an instance of the type, nor would I like to rely on creating an instance just to check its type.

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
  • I don't think there is way to get type by itself but there is a [`GetContainerForItemOverride`](https://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.getcontainerforitemoverride(v=vs.110).aspx) method which creates container and is later overridden. And other thing is that it's protected – dkozl Oct 01 '15 at 17:50
  • Would love to know why this was voted down. – Mark A. Donohoe Oct 04 '15 at 18:03

1 Answers1

0

There are two ways :)

1) you'll need to use reflection or expression trees to call the method since its protected. GetContainerForItemOverride() will return a DependencyObject and then you can use GetType() on that.

2) Or you can call something like treeView.ItemContainerGenerator.ContainerFromIndex(0) to get the container for the 0 item, but that'll only work if you have at least one item in the tree (or control).

SledgeHammer
  • 7,338
  • 6
  • 41
  • 86
  • Both of those require actually generating a container. Is there any way to get the type of the container without actually generating one? – Mark A. Donohoe Oct 01 '15 at 18:40
  • 1
    @MarqueIV - the 2nd one doesn't. It'll only work if an item exists already. Newing up objects is very cheap. Not really an issue. The only other way I can think of thats a total hack is to disassemble the GetContainerForItemOverride() method at runtime and parse it out to see what is being new'ed up LOL... seriously though you're making an issue out of nothing. Just call the overload. There isn't any meta data or property if thats what you're after. – SledgeHammer Oct 01 '15 at 19:31
  • Actually, by your own explanation it requires an item to exist which means the container has been generated, proving what I said... a container has to be generated. More importantly, that also requires the control to be instantiated on a form with items. That won't always be the case here which is why your suggestion unfortunately won't work. – Mark A. Donohoe Oct 01 '15 at 19:33
  • @MarqueIV in that case, your only option is to new up the control and call the GetContainerForItemOverride(). Keep in mind though, you still aren't solving the problem for "real" since a control can have multiple container types and they can be arbitrarily picked at runtime. I.e. TreeView has GetContainerForItemOverride(), but so does TreeViewItem :). So every item in a TreeView can have a different container type. – SledgeHammer Oct 01 '15 at 19:41
  • ...which is exactly why my heading says 'ItemsControl' because a TreeViewItem is also an ItemsControl. Again, given a particular ItemsControl, I'm trying to find the type of its container of which there should only be one. A TreeView is just nested ItemsControls, but at the root, the children are TreeViewItems, which is what I said. – Mark A. Donohoe Oct 01 '15 at 19:43
  • @MarqueIV "I'm trying to find the type of its container of which there should only be one". That's a false statement. There can be multiple types was the point. Any ItemsControl can hold multiple types of containers. Do they usally? Well, off the top of my head I can name one which usually *does have multiple types*: a menu. – SledgeHammer Oct 01 '15 at 19:56