I have a DataTemplate that needs to set the IsSelected property on an ItemsControl's container (such as TreeViewItem, ListViewItem or ComboBoxItem). However, it doesn't know the type of the container until it's passed in to it. Since IsSelected isn't part of a common base class or interface, nor is it a common dependency property registered with AddOwner to the various classes (Duh, MS!!! WTF not?!!), I ended up with this mess...
if (container is TreeViewItem) {
(container as TreeViewItem).IsSelected = true;
return;
}
if (container is ListBoxItem) {
(container as ListBoxItem).IsSelected = true;
return;
}
if (container is ComboBoxItem) {
(container as ComboBoxItem).IsSelected = true;
return;
}
...which not only is verbose, but requires me to modify it if I ever use a different ItemsControl that uses different container types! Not good!
Sure I could enhance it a little by putting this logic in extension methods (damn C# for not having extension properties!!) called IsContainerSelected and SetContainerSelected and putting them on UIElement, then moving the above code inside there, but it's just making the outside neater. The inside is still a mess.
My only other thought is to use reflection and look for an IsSelected property and use that if found, but I'm always leery of doing things like that. However, since there isn't a common interface or base class, I'm not really sure I have a choice here.
For context, I'm sharing a complex data template between several different ItemsControls and the template itself has controls that can receive focus such as checkbox and textbox. However, when those controls receive focus via the mouse, the underlying container item doesn't get selected and whatever was selected before remains so.
My workaround is to use an attached behavior that utilizes the preview events to intercept the focus before it happens and set the underlying item accordingly, which works great when I've hard-coded TreeViewItem or ListBoxItem, etc., but I don't want to hard-code the type since the control shouldn't really care. So that's the part that breaks down.
Ugh!!! Why didn't MS just register the same attached property or at least create an ISelectableContainer interface?!!