Data Binding between non FrameworkElements - can it be done in XAML?

199 views
Skip to first unread message

Zhou Yong

unread,
Oct 8, 2008, 11:04:18 PM10/8/08
to wpf-di...@googlegroups.com
This is an interesting thread in the WPF forum, and I think the OP has raised some of the great points on the design frauds of WPF.

Take a look at it.

My first pet peeve of WPF is the seperation of FrameworkElement and FrameContentElement which doesn't make sense to me:) how about yours?

Yong

Josh Smith

unread,
Oct 8, 2008, 11:07:51 PM10/8/08
to wpf-di...@googlegroups.com
I agree about the FE/FCE split being a bummer.  However, some people have created interesting ways to deal with that fact.  For example: http://blogs.telerik.com/StefanDobrev/Posts/08-06-10/WPF_Series_IFrameworkElement_-_the_missing_interface.aspx

Josh

Zhou Yong

unread,
Oct 8, 2008, 11:17:50 PM10/8/08
to wpf-di...@googlegroups.com
Lovely use of decorator pattern, but the question here is that why we need to write this, what if the public API contract of the FE/FCE is changed?

In all in, WPF is over-engineered in a bad way.

Yong

Josh Smith

unread,
Oct 8, 2008, 11:20:48 PM10/8/08
to wpf-di...@googlegroups.com
>> In all in, WPF is over-engineered in a bad way.

Why do you say that?  I've never felt that WPF was over-engineered.  It's complicated, for sure, and there are definitely a lot of ways to solve the same problem, but I'm OK with that.  What do you specifically have in mind, Yong?

Josh

Zhou Yong

unread,
Oct 8, 2008, 11:23:50 PM10/8/08
to wpf-di...@googlegroups.com
So you think the separation of FE/FCE class hierarchy is indispensable and is a good OO practice to follow?

Yong

Josh Smith

unread,
Oct 8, 2008, 11:25:52 PM10/8/08
to wpf-di...@googlegroups.com
I don't know enough about why they chose to do that to be able to answer that question with any certainty.  It's a nuisance to deal with, but I can only assume that it makes sense for some reasons.  Do you know why the designers of WPF chose to make that separation?

Josh

Zhou Yong

unread,
Oct 8, 2008, 11:30:12 PM10/8/08
to wpf-di...@googlegroups.com
I don't know either and I am glad to know it really:)

John Gossman should know the story behind it, John?

Yong

Dr. WPF

unread,
Oct 9, 2008, 2:26:00 AM10/9/08
to wpf-di...@googlegroups.com

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.  :-)

Dr. WPF - Online Office at http://www.drwpf.com/blog/


rudigrobler

unread,
Oct 9, 2008, 3:05:44 AM10/9/08
to WPF Disciples
WOW Doc...

Tnx for the nice explenation!
>    Dr. WPF - Online Office athttp://www.drwpf.com/blog/[1]
>
> Links:
> ------
> [1]http://www.drwpf.com/blog/

Marlon Grech

unread,
Oct 9, 2008, 3:42:34 AM10/9/08
to wpf-di...@googlegroups.com
as always I am IMPRESSED...... Dr.WPF you are the MAN !!!!!!!!!!!  ROCK ON!!!!!!

Zhou Yong

unread,
Oct 9, 2008, 4:40:49 AM10/9/08
to wpf-di...@googlegroups.com
-> 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.  :-)

Not really dude, if something is common, you'd better refactor them into a common interface, right? I think the trick linked by Josh Smith is really clever, and should be included into the framework, because it's not the responsibility of us developers to write that piece of uninteresting code.

-> 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.

FE and FCE achieve different feature set, but it doesn't necessarily mean that both of them don't have common features/operations, and since someone has said interface based design is great, why having troubling using interface to define common public API here?

Yong

Josh Smith

unread,
Oct 9, 2008, 8:13:02 AM10/9/08
to wpf-di...@googlegroups.com
That's a quality explanation, Doc!  In fact, it was so good, I surfaced it on the WPF Disciples blog (hope you don't mind!): http://wpfdisciples.wordpress.com/2008/10/09/frameworkelement-vs-frameworkcontentelement/

Josh

Bill Kempf

unread,
Oct 13, 2008, 8:47:39 PM10/13/08
to wpf-di...@googlegroups.com
I've been gone for a week folks, so pardon this late reply, but the Doc said something I have to complain about.
On Thu, Oct 9, 2008 at 2:26 AM, Dr. WPF <a...@drwpf.com> wrote:

Since the framework is not built on a language that supports multiple inheritance (and thank god for that!), the divergence was necessary.

Man, I can't agree with that.  Not at all.  Just because it could lead to problems in C++ does not make the concept bad.  Even in C++, MI is used to great effect with few problems quite frequently.  The issues that C++ has with MI (diamond pattern issues, issues with name clashes, etc.) are a design issue with that language, not a general issue with MI.  Eiffel has MI and has NO problems.  It's sad, actually, that .NET couldn't have learned a few things from Eiffel.  MI and DBC are two concepts I *REALLY* wish that we had in .NET.
 
--
Quidquid latine dictum sit, altum sonatur.
- Whatever is said in Latin sounds profound.

War is peace. Freedom is slavery.  Bugs are features.

Dr. WPF

unread,
Oct 14, 2008, 4:06:38 AM10/14/08
to wpf-di...@googlegroups.com

It all begins with one parenthetical remark, doesn’t it?  I guess I should just be happy that you are not complaining about my failure to capitalize the ‘g’ in god.  ;-)

I totally respect your views on this, Bill.  And I don’t think the MI concept is *bad*... I’m just not as convinced as you are that it’s really *good*.  My reason for appreciating the current SI model is that it means we just don’t have to deal with various MI problems.

Note that I’m weighing in here with some hesitation because I have long since lost my true passion for the MI vs. SI debate.  I currently fall in the SI camp as a result of first-hand experience with most of the known MI issues.

I will certainly give props to Eiffel for its approach to MI.  I played with it back in 2004 and I liked the general approach for dealing with things like name clashes.  At the same time, I found myself saying “here we go again” when the provided samples would use the redefine subclause without the select subclause, thereby breaking my polymorphic calls on base classes.  This is by far, the biggest drawback with MI.  It’s not that it doesn’t have the potential to be powerful and useful... it’s that it is so often poorly implemented.  (Yes, you can make the same argument about SI, so I don’t base my opinion entirely on this.)

What it ultimately comes down to is this...  I have yet to see a cost-benefit analysis of MI in which I was persuaded that the benefits outweigh the costs.  I’m aware of the costs first-hand.  What is the great benefit that will move me back to the MI camp?  I’ve heard the theoretical benefits for the last 20 years, but every practical MI scenario I’ve experienced just reinforces my membership in the SI camp.  (It always seems to involve working within some sort of flawed technology like COM.)  [Uh-oh.... there's another parenthetical remark that is liable to devolve.]

All that said, I’m not going to rally against Microsoft if they someday decide to bring MI to C#.  However, I’m pretty sure it will require some CLS changes.  If I recall correctly, when I examined my Eiffel.net classes in reflector, they did not maintain the “is a” relationship for multiple base classes, but were instead flattened.  (It’s been a while and maybe such things have been solved, but I’m guessing there are a few issues in the CLR that interfere with true MI support.)

If I had to place a bet, I’d guess that we will never see true MI in .NET just because of its current reputation (deserved or not).  Microsoft probably doesn’t perceive the required investment as paying off for a feature that most shops will just avoid using.  It would be an uphill battle, for sure, to bring MI back into wide acceptance.  Yes, I’m fine with blaming that entirely on C++.

Bill Kempf

unread,
Oct 14, 2008, 8:09:09 AM10/14/08
to wpf-di...@googlegroups.com
I can agree with a lot of what you said.  I doubt MI will make it into .NET, as I'm certain it would require CLS changes.  Unlike you, I think that's a pity.  I've hit MI issues in the past as well, in C++, but I also was able to put it to tremendous use far more often than I ran into problems with it.  Why throw out the baby with the bath water?
 
I've also never had issue with MI in Eiffel.  The select issue you point out in Eiffel isn't that bad, really, and could be easily dealt with in a theoretical MI supporting C#.  Really, the MI issues have to be dealt with to some degree in C# already, which is why we have explicit interface definitions.  MI adds only the diamond pattern issue, which the language can easily enforce best practices on.
 
Like every language feature, there's room for abuse and misuse leading to disaster.  I hate giving up the power of any feature, in the name of "protecting the developer from themselves".  Expose the feature in as clean and safe a manner as possible, regardless of whether or not there is still room for the developer to shoot themselves in the foot.  After all, they can do that with EVERY feature of any language you want to pick.  This is the same reason I support any and all support for dynamic objects and invocation in C#.
 
In a cost/benefit analysis, I've never been able to consider the costs to outweigh the benefits of MI.  You know at compile time when things are "broken", and simply have to find alternative solutions (which must exist, if SI-only languages can exist).  On the other side, for me it's a daily (almost hourly) occurrence when using SI-only languages like C# and Java when I swear at being unable to use MI.  A mixin solution (possible to implement in .NET with out the need for changing the CLS) would often be enough, but we don't even have that capability.  I'm left with tedious aggregation solutions, which work, but except in the simplest of cases is a pain to code and more importantly, maintain.  Hard to follow DRY principles when the language doesn't support MI and/or mixins.
 
So, I guess we get to agree to disagree. :)  The lack of MI is the only thing I really think C# got incredibly wrong.

Mike Brown

unread,
Oct 21, 2008, 10:30:09 AM10/21/08
to wpf-di...@googlegroups.com
I'd honestly like to see MI treated the same way as calls to unmanaged code (or direct memory manipulation). If I choose to use it, I mark the code saying I know what the eff I'm doing now get out of my way! For the most part, I don't need MI or unmanaged code, but when I do...I'm grateful that I can drop to unmanaged and infuriated that I can't perform MI. Yes I know that in many cases, using containment vs inheritance is more elegant. But sometimes, you've got to put up the china and let the bull run loose.
 
Like I said, I wouldn't care if .NET didn't support telling the compiler that it needs to step out the way in some instances. On the other hand, I can see the drawbacks to MI as well for the .NET team. What happens when some psycho derives a control from a TextBox and a RadioButton or a Panel and a TreeView? Which control's template takes precedence? Do we require the person to provide their own Template? In what order should the events tunnel and bubble? How are dependency properties resolved? Even worse is the fact that with multiple inheritance, you can have more than two base classes. So now the team has to be concerned with how every class interacts with every other class. And that graph of interactions grows exponentially.
 
Again, like I said however, requiring a developer to mark code as unsafe in order to use MI removes the burden from the team to test these interactions and places it on the developer to REALLY know what he's doing.

Bill Kempf

unread,
Oct 21, 2008, 10:41:40 AM10/21/08
to wpf-di...@googlegroups.com
I'll be honest, more often than not all I really need is mix-in capabilities.  It's maddening when you have interfaces like INotifyPropertyChanged, INotifyCollectionChanged, IDataErrorInfo, IEditableObject and others that all require basically identical coding in so many of my own classes.  Delegation works, and is what I use for the most part, but that still requires large amounts of grunt work.  Just provide me with a mechanism to say IDataErrorInfo should delegate to the _dataErrorInfo member and let me go on with life.  That would take care of the VAST majority of cases in which I wish we had MI, and could be easily done at the compiler/language level with no changes to the CLR.

Mike Brown

unread,
Oct 21, 2008, 11:05:54 AM10/21/08
to wpf-di...@googlegroups.com
BTW I still would like the ability to define readonly static fields in an interface as Java allows.

Bill Kempf

unread,
Oct 21, 2008, 11:07:57 AM10/21/08
to wpf-di...@googlegroups.com
Reasonable.  We need a C# vNext request page! ;)
Reply all
Reply to author
Forward
0 new messages