tags:

views:

53

answers:

3

I was just curious if this is a good or bad practice or what the most preferred way of doing this is.

The practice I am referring to is that as I am a newb to WPF as I'm going along I have found it handy and useful to put strings, xdocuments, and domain objects into the Application.Resources in the app.xaml when their data is to be needed across the application, and for the simplicity of the static resource binding by x:key.

Good? Bad? Why? What should I do instead? Please no links to large MVVM tutorials and such, just looking for a concise answer regarding this specific practice, if MVVM has an answer for it I'm glad to hear what it is, I just don't want to read a 6 page tutorial or blog to find out..

+1  A: 

Putting things in App.xaml could be a problem when:

  1. You start branching your application into separate assemblies as the assemblies cannot 'see' app.xaml design-time - you can only find bugs run-time.
  2. You have a magic string for pointing at your resource which is easy to misspell - or worse yet, duplicate by accident.
  3. It is hard later to find the places any given resource is used and whether it can be safely changed ('What was it UpdateFrequency was for...')
  4. You want it to be configurable - the AppSettings part of the app.config file is much better for these kinds of settings.

It's essentially the same problems as using global static variables for settings.

EDIT: Things, I prefer to have in App.Xaml is:

  • Global Styles and DataTemplates - in other words - things used for visual presentation that is there to override 'standard' settings - so usually they have no x:Key tag but rather a TargetType="{x:Type SomeType}"

Hope this helps!

Goblin
+1  A: 

This does make sense for ones shared across the application - "don't repeat yourself". I would also recommend having a project-specific resource that merges the application resources. The controls should reference that rather than the application resources.

This makes the controls in the project more self-contained.

I'd also recommend breaking resources into logical groups and merging them rather than having "one big bucket".

mancaus
Good point on not centralizing the resources at design time, but having them merged at compile time! Can you give an example of how this is done?
Jimmy Hoffa
+1  A: 

I implement an application view model (AVM) object. Anything that needs to get exposed to the application views globally gets implemented as a property in the application view model so that I can get to it via binding. This makes for a nice consistent access method, gets me testability, implements property-change notification, gives me a place to put application-wide commands, all the stuff that you'd expect from using a view model.

The data context for every top-level window is set to the instance of the application view model. So I don't need to mess around with the resource dictionary or remember key values at all. That may sound a little weird at first - why would two windows use the same view model? - but if you want to put the same File/Exit command on every window that the application spawns, this actually makes logical sense. In such a case, the window's data context is set to the AVM, and then it contains a panel whose data context is set to a property on the AVM that's the actual context for that window. As long as you give your window element a name, binding to objects on the AVM is trivial - {Binding ElementName=TheWindow, Path=DataContext.TheProperty} - or you could expose the AVM as a property of the child view models.

The AVM pattern is subject to the same pitfalls as any one-object-to-rule-them pattern - e.g. creating a shambling beast with 200 unrelated properties. The solution's the same: aggregate those properties into service classes.

I generally don't put anything in the resource dictionary that doesn't get created in XAML. I can think of lots of valid exceptions to this general rule, but they haven't occurred in my programs yet.

Robert Rossney
Oh I really like this, this sounds great and I love that the AVM gives a good root representation of the application from an object standpoint making the starting point for understanding the apps design obvious
Jimmy Hoffa
Do you implement an ApplicationModel that the AVM binds to as well?
Jimmy Hoffa
Sure, if one is needed. A lot of what drives that is the need to be able to use the VM objects in Expression Blend - you basically want to be able to instantiate all the objects in your view model without necessarily instantiating any domain objects and using mock domain objects instead. But that all depends on how important Expression Blend is to your development workflow.
Robert Rossney