May 10, 2007
I recently created a design pattern, called “Virtual Branches”, which allows elements that are not in the logical tree to bind against the DataContext in the logical tree. Shortly after I posted the article about virtual branches, Douglas Stockwell posted an interesting response which expressed doubt regarding the usefulness of the pattern.
Stockwell demonstrated how the problem shown in the article could be solved without using a virtual branch. His solution was to hoist the demo’s IsMultipleOfValidationRule into the Window’s Resources and bind the Slider’s Value directly to a Divisor property on the rule. Then he referenced the ValidationRule as a StaticResource from the TextBox.Text’s Binding. This works, but I feel strongly against this design (as does Stockwell).
Binding a Slider to a ValidationRule used by a Binding in a TextBox introduces a very artificial coupling. The only relationship which the Slider and ValidationRule share is that they both need to access the same property on the data context object. Specifically, they both need access to the Divisor property on a DivisionNumbers instance. That’s all they have in common. There is no reason why they should be aware of each other.
Using a virtual branch in this situation removes the unnecessary coupling. The ValidationRule is not directly dependent upon the Slider to ensure that it has the correct Divisor value. Later if the Slider is removed, or the ValidationRule is created programmatically, or alternate ways for the user to modify the Divisor are introduced, there will be no knots to untie.
Virtual branches provide a layer of indirection which allows you to bind against properties on the domain object, not against properties on other objects in the element tree. In general, this is a better design tactic because it promotes ignorance (i.e. elements don’t know about each other). Ignorance can be bliss.
May 10, 2007
Over time I have received an increasing number of WPF questions from random people. Many of them are sent directly to my personal e-mail account (I’m not sure how people find that address), and others are posted as comments on unrelated blog entries. I appreciate that folks look to me for answers, that’s quite a tip of the hat. However, it is much better to use Microsoft’s WPF Forum to post a question and get answers to it. Here are a few reasons why:
- If the entire question/answer thread is carried on via e-mail, nobody else will be able to read it later. The answer becomes a “one time” solution which must be recreated the next time someone has the same question. If the thread is on the forum, then it is very easy to find it via a quick Google or forum search.
- I might not know the answer. Someone on the forum will. Keep in mind that folks from the WPF group at Microsoft answer questions on that forum, as well as a bunch of other very knowledgeable individuals.
- I might not have the time or interest to answer your question. Believe it or not, I have a job, a girlfriend, social engagements, family to visit, pet projects to work on, a piano to practice, articles to write, blog posts to create, etc. 🙂 I don’t always have enough time or interest to dig into someone else’s problem. However, someone on the forum will. It’s amazing how quickly most questions receive an answer on the forum. It’s like a feeding frenzy over there (yeah, I’m looking at you Drew! 🙂 ).
If you are developing in WPF, be sure to add the WPF Forum to your Favorites list. Also be sure to read Rob Relyea’s brief WPF Forum Best Practices post before using the forum.
Please keep in mind that the intention of the post is not to shoo people away. Quite the contrary. I encourage people to join me on the forum. If you have a question which pertains to a particular blog post of mine, feel free to drop a question about it in a comment right then and there! Just don’t ask unrelated questions in a post’s comment, or in an e-mail, because of the reasons listed above.
To end this post on a lighter note, here is an amusing (and 100% true) story. A while ago some guy e-mailed me a very poorly worded question, asking how to do something; I’m still not quite sure what. I didn’t have the time or inclination to help out, so I didn’t reply. Shortly thereafter he followed up with (and I quote):
“I am very disappointed for you. I told you this is extremeley urgent for me and you ignore my query. I told you my deadline is soon and you do not give me any help at all. You must give me solution TODAY, that I have no time to wait for you and my patence is finished.”
I kid you not! 🙂
May 7, 2007
I just discovered that Paul Stovell posted a set of XAML and WPF coding guidelines. I really like his advice on resource organization. He provides a scalable way to structure your project’s directory system such that it is easy to determine where a resource declaration should be placed, and a naming convention which makes it easy to find where a resource is declared.
The one suggestion I would have added is that resource keys and x:Name values should not simply reiterate the type name of the object. An object’s key/name should reflect how it is used, as well as the type name…sort of like hungarian notation only not as cryptic. There are some situations where this is not possible, such as declaring an instance of a value converter in a commonly merged resource file, but it usually is. For example:
<!– Bad –>
<SolidColorBrush x:Key=”BlueBrush” Color=”Blue” />
<!– Good –>
<SolidColorBrush x:Key=”DaytimeSkyBackgroundBrush” Color=”Blue” />
If you were to look at those two resource declarations in a project you’ve never seen before, wouldn’t it be easier to immediately grasp the purpose of the second brush?
May 6, 2007
I was helping someone out on this thread in the WPF Forum the other day. Basically the guy wanted to bind a property on a custom ValidationRule to some value in a template’s DataContext. This turned out to be much tricker than it initially appeared. I figured out a way to do it, by designing a technique which allows you to “attach a virtual branch” to the logical tree. I won’t bother describing it in detail here, because I just posted a CodeProject article about it: http://www.codeproject.com/useritems/AttachingVirtualBranches.asp
In my opinion, this is the most interesting and useful contribution I’ve ever made to the WPF community. I’m looking forward to seeing how people use this pattern in their applications.
May 5, 2007
This blog entry demonstrates the fundamentals of binding a WPF TreeView to a DataSet with two related DataTables. The technique presented herein could easily be extended to fit more sophisticated requirements, such as binding to more than two tables.
Many applications need to display hierarchical data in a TreeView, and often that data is retrieved from a database. In many situations the developer just needs to bind the TreeView directly to the DataSet which was populated with database data; creating custom domain objects and collections of those objects can be overkill sometimes. If you are currently in that situation, rest assured that it is actually fairly trivial to do this in WPF. 🙂
The basic gist of the solution is to bind the top level of TreeViewItems against the master DataTable, and then bind against DataRelations for any descendants of the root nodes. You need to use a HierarchicalDataTemplate for every non-leaf level of nodes, in other words, only the very lowest DataTable in the hierarchy is displayed with a non-hierarchical DataTemplate.
Let’s just get right into an example. Here is a method in a class called DataSetCreator which creates a DataSet with two related DataTables:
The resultant DataSet has two DataTables (‘Master’ and ‘Detail’) and one DataRelation (‘Master2Detail’). We want a TreeView to display the Master rows as top-level nodes and the Detail rows as children of their respective parent node. Here is the XAML for a Window which contains a TreeView configured to load and display that data:
If you had, say, three related tables (Master –> Detail –> DetailInfo) then you could have the ‘DetailTemplate’ be a HierarchicalDataTemplate whose ItemsSource was bound to the DataRelation between ‘Detail’ and ‘DetailInfo,’ and the ItemTemplate a DataTemplate which displays the pertinent information in that table.
When you run the demo application and expand the root nodes, the TreeView looks like this:
Click here to download the demo project. Be sure to change the file extension from DOC to ZIP and then unzip it.