Sunday, August 24, 2008

Item Presentation Models for WPF

After two weeks of work (and some play), I've finally posted my Item Presentation Models for WPF article to Code Project. This is my first Code Project article ever, so I'm excited about it. I hope readers find it useful and I look forward to their feedback.

Tuesday, August 19, 2008

Naming domain-specific ItemPresentationModel objects

I've decided to follow a rather unconventional naming pattern for domain-specific presentation-model classes — suffix them with "View". I am aware that this naming breaks away from the conventional terminology of MVC and its derivatives, in which "View" refers to the UI layer. So I devote this blog entry to digressing my reasons.

Outside the scope of MVC-related design patterns, the word "view" has a more general meaning that's applied in varying contexts. SQL, for example, uses it to mean a derived view of base data. Closer to the present topic, WPF includes the CollectionView class which is a sort of presentation-model. People who prefer that "view" strictly refer to the UI probably hate this choice of class name. However, appending "ViewModel" or the even longer "PresentationModel" to all my class names is verbose in my opinion.

For the above reasons I instead use the suffix "View" as an acceptably short alternative for my domain-specific Presentation Model classes. By doing so, I intend to invoke the word's general meaning of the sense that the presentation-model provides a derived view of the domain object. Another interpretation is that the presentation-model provides an interface for the domain object that makes it fit for presentation; the presentation-model is therefore an abstract view (presentation) object. This latter interpretation is useful since it emphasises the presentation-model's actual purpose, which is that it facilitates visual display (in that sense, Josh Smith's original "Presenter" suffix doesn't sound half bad).

I am aware that this naming breaks away from every quasi-standard in the literature of MVC and its derivatives. Even the WPF library doesn't use it consistently. That is, they use the word "View" in its more traditional MVC sense as well, as in ListView and TreeView. If instead WPF named those controls "ListControl" and "TreeControl" — which would be consistent with many other controls in their library such as ContentControl, ItemsControl, UserControl, and TabControl — then I would find their choice of "CollectionView" more acceptable. In any case, I still find their suffix "View" to be so much more aesthetically pleasing than the alternatives, so that's what I choose to use in my own projects. Such a choice, however, has implications only within the scope of individual projects or organisations. Therefore, others can use whatever naming convention they find to be the easiest to live with.

Saturday, May 10, 2008

Revisiting bidirectional association helpers

The one-to-many and many-to-many helper classes in my ObservableCollections project make it easy to maintain in-memory the semantics of bidirectional associations, by keeping an association's references in sync in both directions. The way these helper classes are now, they work only in situations where the many-side is constrained as unique and is non-indexed, i.e. the corresponding collection is an ISet. However, I've encountered a situation in my main project where an association's many-side is indexed, i.e. the corresponding collection is an IList. So I'm revisiting the ObservableCollections project in order to accommodate this need.

Looking back at the bidirectional association helper classes after so much time, I realised how confusing the class and method names have been. So the first step was to rename them. For starters, I renamed the SetContainerToEntityAssocSync class to OneToManyAssocSync to reflect the more general (albeit incomplete Although I will add support to the newly named OneToManyAssocSync class for indexed collections, this more general name isn't completely applicable since I won't be adding support for non-unique collections as well.) desired applicability. And I renamed the SetContainerToSetContainerAssocSync class to ManyToManyAssocSync. After that, in the OneToManyAssocSync class, I changed other occurrences of "setContainer" to say "one" or "oneSide" since it has a multiplicity of one in the relationship. And I changed "entity" to say "many" or "manySide" since it has a multiplicity of n in the relationship. Finally, I renamed some miscellaneous variable names so that they, to, will be consistent with this new terminology.

The next step was to modify the OneToManyAssocSync class's UpdateOneSide method, along with the ManyToManyAssocSync class's UpdateOtherSide method, as follows. The other side's collection must be cast not to ISet, but to the ancestor type ICollection which is common to both ISet and IList. I actually ended up using the generic ICollection<T> since the nongeneric version strangely lacks methods for adding, removing, and checking for containment of items. The code now works in cases the collection type is an IList; however, it only works when the uniqueness constraint is being applied to the IList, which is fine in the case of my main project. It will not, however, work for bags or lists with multiple occurrences of the same item. I included checks for this boundary condition.

Friday, January 18, 2008

Closable TabItem in WPF

Having finally reached the user-interface implementation step in my current programming project, I must first lay the foundation for the program's tabbed document interface (TDI). It's a TDI of the style seen in Firefox and Internet Explorer, where each tab includes it's own close button. Additionally, in my program the set of tabs is fixed and the user can reopen a tab (via a menu) after it's been closed, which makes it appear at its original position. WPF's standard TabItem control doesn't have a close button, so in order to include such a tab in your own program you must find or create a custom control that does the job. You can download the result of my effort—a Visual Studio 2005 solution—here (updated 2008-Feb-11).

The included ClosableTabItem derives from TabItem and provides the functionality you need to easily add close buttons to your program's tabs. The sample application additionally includes for each tab a corresponding item on the 'Tabs' menu, with a check mark indicating the tab's current visibility. After a tab has been closed, a check mark no longer appears on it's menu item. This provides a means for the user to reopen a previously closed tab by selecting a menu item with no check mark. If the user selects a menu item that's currently checked, the item gets unchecked and the tab is closed. But I am not sure this latter behaviour is the most natural/useful. Perhaps it would be better if, rather than closing the tab, it gets selected and it's contents are brought to the front. In that case, I would rename the menu from 'Tabs' to 'Switch Tabs' similar to the 'Switch Windows' menu in Microsoft Word 2007. I am not sure which behaviour would make for a better user experience, so please send me your feedback.

Soon after I started creating the custom control, I came across a blog post which looked like it already did the work for me. Upon looking at the solution's source code, however, I became disappointed with it's architecture. Rather than reusing the Style and Template of it's parent TabItem type by deriving from it, it completely replaces them. This flows contrary to the object-oriented principles of code reuse which I have internalised. So I decided to continue creating my own custom control. At first I thought that after adding the BasedOn attribute onto my custom control's Style element, I'd just need to write a few lines of code then be done with it. But it actually took more work than that, involving WPF features such as data templating, property bindings, and routed commands. The resulting custom style code is a lot shorter than the competition's, though—less than 90 lines as opposed to about 170—so I consider it an improvement.

Tuesday, December 11, 2007

Camping trip to Doi Inthanon

I can't believe the extent of our travels in just four days. We went shopping in Bangkok on Friday afternoon, where I bought a new torchiere (floor lamp) for my home office. Much to our own surprise, we managed to make it to Chiang Mai by Saturday morning. We bought our new camping gear and then had an excellent camping trip with our friends, David and Jeab. We were back in Bangkok by Sunday night, and then on our home island by Monday evening. Whew.

When we departed our home Thursday evening, we had the intention of heading all the way to Chiang Mai. Even before reaching Bangkok, however, we decided it wasn't worth the additional eleven hour bus ride. We slept a night at my girlfriend's parent's house in Bangkok, and went shopping the next day. That evening, however, my girlfriend's mother phoned from work saying her niece (my girlfriend's cousin) will be driving with her boyfriend to Chiang Mai that very evening. We scrambled to hitch a ride, and arrived in Chiang Mai the next morning.

The highlight of the trip, without a doubt, was ascending to the peak of Doi Inthanon in Chiang Mai on Sunday morning at 6 a.m. Being the highest point in Thailand, it's a popular tourist destination among Thais. Now is the country's "cold" season, and that peak is the coolest place. Everyone goes there at 6 a.m. because it's the coldest time of day. It's for the thrill (?) of feeling freezing cold, as if in some foreign country.









Thursday, December 6, 2007

Collections for WPF and NHibernate

My current programming project is on the Microsoft .NET platform, and I'm writing code in the C# language. I'm using NHibernate — a popular object/relational mapping tool — in the data access layer, and Windows Presentation Foundation (WPF) for the user interface. One of the features making WPF so attractive is data binding. Although I was initially disappointed when I found out that NHibernate's collections don't work correctly out-of-the-box with WPF data binding, I soon found Gary DeReese's blog entry which provides a (partial) solution. Gary's "NotifyingCollectionDemo" shows how a custom collection type can be built to rectify NHibernate's shortcoming. After studying how his ObservableList (which is actually an observable bag) was created relative to the NHibernate API, I began work on my own "ObservableCollections" project which includes three custom collection types: observable bag, observable list, and observable set.

I've finished creating these custom collection types, so you can download the result now (updated 2008-Dec-10) to use in your own projects. The zip archive contains a Visual Studio 2005 solution that includes three projects. The "ObservableCollections" project is the library containing the custom collections. The "ObservableCollections Demo" project is a WPF program that you can run to play with the contents of a sample set and sample list collection. And the "CoreHelpers" project contains some miscellaneous helper classes that I use in various projects. Before running the demo project, however, you'll need to do the following:
  • Add references to the library and demo projects, pointing to the following NHibernate assemblies on your computer (unless already in the GAC): NHibernate, Castle.DynamicProxy, Iesi.Collections, and log4net.

  • Change the absolute path of the database in the hibernate.cfg.xml file to match its location on your computer.
The "CoreHelpers" project includes a OneToManyAssocSync helper class that makes it easy to maintain in-memory the semantics of a one-to-many bidirectional association. The demo project shows how to use it. There is also a ManyToManyAssocSync class for easily maintaining many-to-many bidirectional associations. (See this blog entry for a note about the renaming of these classes from their former names.)

Sunday, January 30, 2000

Senior Year at Lewisburg Area High School: List of Laments


  • I had been continuously in search of somewhere quiet to work in the school building, and no such place exists. Study halls, especially in the cafeteria, are filled with people talking. Even the library is typically noise-filled, usually a teacher talking to a single student.

  • Senior year study halls in the cafeteria never provided silence in which to concentrate on work. The library, however, was usually considerably quieter. Nonetheless, in my study hall, when students asked the study hall teacher for a pass to the library (or other places such as to the guidance office), he would demand that the student wait until role was called. Role usually took, while this teacher demanded silence only while it was being called, around 10-15 minutes, or ¼ the period.

  • The guidance office did not provide me with a quiet place to take my AP exam. I was the only one taking that particular exam. During the first segment, there were multiple announcements over the intercom that interrupted at least 20 minutes of test time. Those interruptions also greatly threw off my concentration for periods of time in between. The College Board did not weigh my exam grade in consideration of this.

  • Teachers typically waste a great deal of time at the beginning and at the end of class periods. The content of most classes is largely review and not new material. There are very few AP courses offered, in a very limited range of subjects.

  • My senior year Trigonometry teacher would spend a considerable amount of time at the beginning of each class talking about professional sports.

  • Both classes I've had with the Health teacher have been a pathetic demonstration of the immense expanse of uselessness which extends across most of the school day. This teacher often spends half a class period talking to the entire class about such thing as school basketball teams, or to certain students about somewhat personal issues. The Health class I had with him sophomore year had only one class period which I feel I actually learned something. That day we watched a National Geographic special. Eighty percent of the class time for that class sophomore year, was not even spent talking about course material.

  • The Anatomy class I took with the above teacher senior year, in the time we were actually talking about the course material, was a waste as well. The class consisted simply of memorizing names of bones, muscles, and processes but with no intent of this teacher on giving us an understanding of these. I and my former classmates may now recognize the name of a muscle, bone, or process if we heard it spoken, but any conceptualization of it would escape us.

  • When I mentioned to my Junior year English teacher that I saw fault in the fact that through-out high school we only focused on British and American (predominantly white American) Literature, he did not express any reciprocal concern or desire to change this fact.

  • The only book in all of high school not written by a European or white American that I was assigned to read, was in my senior year AP English class, a class which not the majority of students are opt to taking. The discussion of this novel, lead by the instructor, was incompetent, insufficient, and rushed. I did my end-of-year research paper on this book and read things I was amazed were not mentioned in class by the instructor. From the instructor, I was introduced to such racism as "dark black men" intimidate her because of their blackness. In this particular case, I confronted her in front of the class. She immediately grew defensive and left the room in a furry.

  • Computer equipment and supplies are plentiful. This does not mean, however, that they are used effectively. The majority of the time, printers in the library or Tech-Ed lab do not work properly. I've wasted a large amount of time simply trying to print a word processor document. Student "administrators" are largely depended on for maintaining the equipment. This provides a scapegoat for the responsible faculty members, but is not effective enough in maintaining the equipment (printers, scanners, CPUs, etc.). In addition, the faculty does not have the training or knowledge in rendering the capabilities of the expensive computer equipment. Much of the technology, purchased with taxpayer's money, goes to waste.

  • Most attempts at individuality are discouraged by the repressive atmosphere maintained by the administration and faculty. This is reflected in the curriculum as well, in which diversity in English literature presented to the students is non-existent.

  • The Junior year english class consisted mainly of filling out "study guides" while we read classic novels. The tests on these novels consisted of questions taken directly from the study guides. The study guides consisted largely of specific details from the novels, most of which were completely irrelevant to the underlying meaning. I'll pick our reading of Edith Wharton's Ethan Frome as an example. One item on the study guild was the color of the character Zeena's rocking chair. For the exam, we also had to recognize a photograph the teacher took of a hill, which is the supposed basis of the fictional hill the characters Mattie and Ethan took their fateful sled ride on. We were not at any point asked to uncover our own thought and interpretation of the novel. We were simply told what to "think" of the novel. The teacher's entire course was built on making us trivia wizards in the subjects we covered. But being able to name the color of Zeena's rocking chair from Ethan Frame, does not do much in the way of making us brighter people.

  • Full day detentions, known in Lewisburg High School as "TRAC," are frequently assigned to students for an extremely wide range of offensives. The first instance in the school year a student is assigned TRAC, he/she is kept one day in the "TRAC room." If there are additional "offenses" that school year, the student is kept three consecutive days, during which he/she is not allowed to attend any class other than gym. The concept of being given an entire day, or three days, to catch up on work is very appealing to many students, and indeed if one is lucky enough to have TRAC on a quiet day, it can be quite productive. However, for most individuals a typical day in the TRAC room can be very unproductive. The TRAC "supervisor" is also a Special Education teacher. He is more often than not tutoring students in front of the room, speaking load and clear so everyone in the room hears him. In addition to this continuous interruption, this Special Education teacher often holds conversations with other staff members, also loud and clear and in front of the room.

  • This Special Education teacher is often in a bad mood, the unpleasant result of which falls on whoever has TRAC that day. Such days, which are most days, result in students who have TRAC that day, having TRAC one or more extra days. This perpetuates the situation of many who are consistently in TRAC. This teacher takes more of an initiative in tormenting individuals who are consistently in TRAC, who also happen to be individuals with parents less concerned than most about such injustices. In one particular instance which I witnessed first hand, a student who was a frequent roomer in TRAC, was "upgraded" from one day remaining of TRAC. This was a direct result of the teacher's bad mood that day.

  • The only especially good English teacher I had in the high school, was not a faculty member, but a student teacher from Bucknell University. She had a creative and energetic approach to teaching, from which I feel I and my classmates benefited greatly. I also feel the spanish teacher has a creative and energetic approach to her Spanish courses. Honors Chemistry, which was taught by a teacher now retired, was also a very benefiting and useful course. However, these are only exceptions in this item. They make up an extremely small fraction of the classes offered at the high school.

    Overall, I should summarize the productiveness within the school. The atmosphere of the high school is NOT one of productiveness, as some of the above examples illustrate. For the most part, it is not one of learning either. There are only a few exceptions to this, which are shown in the previous item. As a whole, I can confidently say that the content of most courses is a waste of time, from which I have not drawn any benefit. In class time which is actually being used, 95% of the focus is on discipline and being told what to "think," and 5% of the focus is on academics and actual thinking and understanding. Upon my graduation, not one Ph.D. in any course subject was teaching at the high school. This list of laments could continue on for miles with specific deficiencies noted in my senior year and in the proceeding years, but I hope I have provided a sufficient sampling.