FrameworkElement (FE) derives from UIElement. FrameworkContentElement (FCE) derives from ContentElement. Since the framework is not built on a language that supports multiple inheritance (and thank god for that!), the divergence was necessary. There are parts of ContentElement that you wouldn’t want in every FE and there are parts of UIElement that you wouldn’t want in every FCE.
FCE basically exists to support the text formatting engine (which can be found in the MS.Internal.Text namespace). There are a few non-text classes that derive from FCE, but they do this just to be lightweight.
The goal was to make the programming experience for dealing with an FE and FCE as similar as possible. If anything, I think this makes the framework *more* elegant.
You can think of an FCE as having everything an FE has except support for layout/rendering. Of course, this is no small feature and you certainly would not want that kind of overhead in every text element. Imagine the perf if you tried to render every textual stroke using WPF’s layout engine… text is far too complex.
True, it’s weird to see the exact same properties, methods, interfaces, events, etc, defined on two completely different base classes. But I guess my general response is a big shrug. As long as Microsoft is willing to maintain the code, I don’t have a problem with it. (And in truth, much of the code shared between the classes is codegen’d anyway during the build process, so its really not that hard for them to maintain… clever chaps!)
Sidenote: IFE vs. LIFE: A mnemonic we used to use is “LIFE begins at UIElement”. That is to say, every UIElement supports Layout, Input, Focus, and Events. ContentElement gives you everything but the ‘L’. As such, the intersection of functionality between an FE and FCE is the IFE portion.
I recommend creating a helper class if you want to treat the IFE portion of framework objects in a polymorphic manner. It’s easy enough to implement… in fact, you can steal most of the implementation from the internal FrameworkObject class. 🙂
Content Source: Dr. WPF