I ran into an interesting case for this just today. I'm building a UI that includes a collection of FlowDocument
s. These items are presented in a ListView
, one of whose cell templates is a RichTextBox
.
The first problem I ran into is that the Document
property of the RTB isn't a dependency property, so you can't bind to it. Fortunately, some intrepid developer out there ran into this problem before I did, and implemented a RichTextBox
subclass with Document
overriden as a dependency property.
All was well and good until I implemented drag/drop reordering of the collection. Here I discovered one of the reasons why Document
isn't a DP. Changing the order of the collection doesn't actually change the order of the objects they're bound to; the items that moved just refresh their binding targets. And glory be, if a FlowDocument
belongs to one RichTextBox
, you can't assign it to another. Reordering these FlowDocuments
breaks the UI, which is a problem because the whole reason I'm doing this UI in the first place is for reordering these items.
The hammer that I decided to hit this with was to make the RichTextBox
a property of my view model. That way, when I move the FlowDocuments
around in the collection, the RTBs that own them move with them.
Personally, I don't give a fig about whether or not this class is unit-testable. That's not what makes this the wrong answer.
What makes this the wrong answer is that now that I've put this component into my class, it's not part of the event routing system anymore. If I change the FontFamily
on my application-wide FlowDocument
style, these controls never hear about it. I also can't bind anything to them. (Not easily, at least.) There are probably other problems I haven't thought through yet.
I'm not quite sure what the right answer in my case is going to be yet. I think that I may have to fix my bindable RichTextBox
so that it maintains two FlowDocument
objects: the one exposed to the world by its Document
getter and setter, and the one inside the control itself. (That is, when something sets the Document
property on the object, it saves that value in its private field, and then copies the document's content into the content of the base Document
property.)
That's a very long-winded way of saying, "creating WPF objects in the view model seems like a pretty bad idea now that I'm doing it."