Geeks With Blogs
Mike Kenyon Hoarked

So, next step is to get some business modules in place.  I’m going to start with the browse module and I’m doing it for two reasons.  First of all, because it’s the easiest.  Second of all, because it doesn’t really have any connections out to other modules.  The reverse is true, but not that way. 

Overall Design

I’m thinking that I should be able to pull this module off with a total of three views.  First, one view to list the different types of things that you can browse (categories, movies, people, & songs).  Second, a view to show the list of whatever they picked on the first list.  Third, I’m going to need a detail view page.  Theoretically, and I do stress theoretically, I should be able to track all the differences between them via styling and suffice with just that. 

Mode Button

My first goal is to get the browse selector on.  In the back of my head, I’ve got a mental image of the a series of slick buttons in half-transparency that pop when you do a hover-over and clicking each sends you to the root.  Since you can only be in one mode at once, a radio button makes sense.  However, all of that is me in the designer roll and I shouldn’t be there now.  So, what I’d like to do is pop out the ViewModel and let styling take care of it.  I found a gnarly little bug which I reported up to the P&P crew that forces anything displayed as a View to inherit from DependencyObject.  Not the best thing, but it doesn’t really hurt me to do so at this point, so until they get that fixed, I’m good with making my ViewModel inherit from DO.

All I should have to do now is put a data template on the ViewModel type to make it appear as a radio button and bind it’s click to the Activated command on the ViewModel. 

Why Resources Suck

There I said it.  The cat’s out of the bag and it’s not going back in.  Resources suck.  [Editor’s note:  The author is equally likely to say that resources are the best thing ever invented by man … depending on who’s side of the war they’re on at the moment.]  They’re buggy, drop errors and leave you doing your best James Dean impersonation for hours as you try to figure out why X is in the wrong spot, is the wrong color or is just plain wrong.  They’re also incredibly powerful and this occasional urge to through your computer … and the WPF team … out the window is part of that pain.  And in a modular application, this just got worse.

In a non-modular application, my root would have full-connectivity to all the modules and I’d just through the style into any of the resource files included by the main window of the application and I’m 5x5.  Sadly, putting this in a fully modular context slowly eats away my options. 

First, one of the reasons to make your application modular is to be able to treat parts of the application as plug-ins, which you really can’t do if there are compile-time references between them.  So, putting the style into the main application won’t work because it doesn’t know (and shouldn’t know) what my ViewModel is and should not care. 

Second, there’s the question of where to register the styles into.  Every control has a ResourceDictionary, but I’m not registering a view, but rather that display model behind that view.  So, my options are really registering it into the Application itself or into the MainWindow.  I’ve found that resources up in the Application don’t get included when you’re using the default bootstrapper configuration, which is unfortunate.   This has driven me to put all the “top-level” resources I want access to into the MainWindow.  This could have problems if I’m in a multi-window situation, but in general should be okay, at least for this application.

So, I decided to create a service that would put resources in the MainWindow’s merged resource collection. This lead me through a series of three hoops.

First, I figured I would do things the OO way and make my ResourceDictionary (in a file called BrowseResources.xaml) a derived ResourceDictionary type and load that.  Sadly, this does not work.  You can certainly add a x:Class tag on the type and make it a derived class. You can create one.  It has no resources.  Unlike everything else in WPF, ResourceDictionary’s don’t parse their contents on creation. They load themselves from their Source attribute later, so though you end up with a derived type, you don’t get the nice OO way to represent resources.

Second, that left me with needing to define the location of the resource file.  URI’s are relative to the application, by default, so just supplying the file name doesn’t work.  You have to whip out the pack URI.  For those that are not familiar, here’s what one looks like, in the context of loading this file.

service.RegisterResources(
    new Uri("pack://application:,,,/Browse;component/BrowseResources.xaml", 
        UriKind.RelativeOrAbsolute));

I consider myself reasonably smart, but I can’t figure these damn things out.  It’s a strictly voodoo part of my job.  I just copy an old one that worked and make the necessary modifications.  I’ve read through the documentation about a dozen times and I just can’t make it stick.  I’ll get it for a while, and then something more meaningful (like belly-button lint) takes its place.

Third, I got the resources to load and they still didn’t take.  It’s there, just not getting used.  So, for the time being I’ve commented out, used a hack in its stead and thrown out lifelines to others trying to figure out why.

As a final thought, I’ve gotten into two habits that make my life much easier on the binding side.  First, I always derive my ViewModel from DependencyObject, this gives me some flexibility on the order in which things get set.  The second practice is to always either set the model before the call to InitializeComponent() in the constructor or to make it a dependency property itself.

Navigating the Situation

So, I love agile because it gets me going and my assumptions are generally good enough to get me most of the way without too much re-work.  Occasionally, I make a bad call and have to rework almost immediately.  This would be one of those days. 

I realized as I tried to get the content list view in place that what I had in my mind was kind of browser-like.  You pick say “People”, go back, pick “Movies” instead.  Then you drill in on “Tropic Thunder” and then “Robert Downey, Jr.” to see that he’s also in Iron Man which was also nominated (for sound effects I think).  That’s a navigation app.  Crap.  Okay, so the ContentRegion as I have it defined has to go.  There’s no direct support in Prism for Navigation, so I guess I’ll have to add it.  This means two things.

It means adding a region adapter for the Frame class.  Frame is a ContentControl, so I guess the system would work, but the semantics would be all jacked up.  It wouldn’t provide the history semantics that we’d want.  I think it’ll also mean adding a service because some things that you’d want to do are hard to do from the region interface (like clear out all history). 

After a lot of soul-searching (and searching those wiser than I), I’ve given up.  Navigation isn’t going to do what I want.  The default content control behavior is close .. very close.  I’m a little disappointed by this, but in the process I’ve found a bit of a jewel.  You should surely check out the Helix project by David Hill.  This is a better version of Navigation that would probably due 90% of what I need rather than the 70% in WPF proper, but it’d take me to long to integrate it in the first cut.

Entity Framework Woes

I have a love-hate relationship with the entity framework.  For some things it absolutely rocks, for others, it’s not that great.   A problem that I encountered trying to get my foundational module to work is an illustration of that in the small.  It took about 10 minutes to write the HollywoodService class, it was REALLY easy.  On the flip side, it took about an hour to figure out why the damn thing wouldn’t load on me.  Seems that when you don’t have direct references from the main executable to the DLL in which the entity model is located ,the connection string which is automatically generated is incorrect.  The system generates a connection string that looks like this:

"metadata=res://*/OscarsEntities.csdl|res://*/OscarsEntities.ssdl|res://*/OscarsEntities.msl;provider=System.Data.SqlClient;provider connection string="Server=(local);Database=Oscars;Integrated Security=True;MultipleActiveResultSets=True""

What will work is something like this.  The “*” is replaced with the name of the DLL that contains the file.

"metadata=res://OscarsNight/OscarsEntities.csdl|res://OscarsNight/OscarsEntities.ssdl|res://OscarsNight/OscarsEntities.msl;provider=System.Data.SqlClient;provider connection string="Server=(local);Database=Oscars;Integrated Security=True;MultipleActiveResultSets=True""

After a little effort, however, we have a system with an operational Browse module.  Next up, the Guessing module.

To see the current code check here

Posted on Wednesday, February 4, 2009 1:14 PM | Back to top


Comments on this post: Creating a WPF Application With Prism v2 – Browse Module, Why Resources Suck & Navigation Horrors

# re: Creating a WPF Application With Prism v2 – Browse Module, Why Resources Suck & Navigation Horrors
Requesting Gravatar...
Glad it wasn't just me with the resources issues. The other problem is that the more to add them programatically the more the designers complain. Which leads you to ignore all designer errors - which means you miss the real typos.
Left by Joe on Mar 26, 2009 9:17 PM

# how to get the wpf control s content from default language
Requesting Gravatar...
iam using wpf application.
appklication supports multi language for this pupose we create resource dictionary for control content .and geeting the content form the resourcedictionary if the content missing in resource dictionary .we are getting exceptions how to avoid this.
Left by raghu on Aug 28, 2009 5:44 AM

Your comment:
 (will show your gravatar)


Copyright © hoarked | Powered by: GeeksWithBlogs.net