WPF/MVVM Status app: Update 1

I’ve been continuing to dabble with my little status app (described here and here). I wanted to write down some of the lessons learned so far. Also, I think I have a decent plan for how to finish this app too.

Models and ViewModels (MVVM):
As you may recall, this is a WPF application that is using the MVVM pattern for separating the data from presentation. You may also recall that each window/control/page/etc can have exactly one DataContext. Also consider that user controls will have access to the parent DataContext, if you want.

So, from a video I saw, that is what I was originally doing. I had a directory for Twitter, Mail, Weather – and in there were the models, viewmodels, and user controls for that respective functionality. However, from the main window, I had sort of a "container" viewmodel that referenced those sub-viewmodels.

The first problem was because the user control doesn’t have it’s own, direct DataContext, that means that you won’t be able to see what the control looks like at design-time. That isn’t a showstopper, but wasn’t ideal. That meant that I couldn’t just "Apply Databinding" from the property window, instead I’d have to type the XAML. In other words, the DataContext was implied at run-time, but not explicit at Design-Time – which means I couldn’t use the nice little time-savers in the IDE.

Also, as I was refactoring and cleaning up some code, it became apparent to me that "window", shouldn’t be controlling everything. Each user control is capable – and it’s ideal even, if it manages it’s own DataContext. In this particular case, that makes more sense because there isn’t really anything common between these pieces of functionality.

So I refactored each piece of functionality into it’s own user control – even the date and time. Now, every user control has it’s own (local) DataContext. That means that in design-time, I actually see working functionality. For example:

image

This is what I have now for a structure:

image

Polling and Timing:
Now that each user control has it’s own DataContext, it seemed logical to put my polling logic in the ViewModel. So each ViewModel uses a DispatcherTimer. On the Tick event, it checks to see how long it’s been since the last poll. Once a certain period has passed, it refreshes the data.

In the case of the datetime, I do that once per second. For Twitter, I do that once ever 150 seconds. For weather, I do once per-hour, at :15 after the hour. Lastly, for mail, I have been going back and forth with a couple of components, but ultimately when I get something working the way I want, I’ll likely poll every :15 minutes, if I use POP3. If I use IMAP, I shouldn’t need to poll and will instead be notified when there is new mail.

While I was at it, I realized that it was slightly annoying not knowing how stale the data was on the screen. So – since each ViewModel knows how long it’s going to be until it refreshes the Model again, I decided to expose a property, that I bind to a progress bar. I didn’t want to get too obnoxious with the progress bar’s, but I wanted something kind of subtle. I think this works well:

image

As you might imagine, the progress bar under the time moves every second where :60 seconds is 100%. For weather, that polls once per hour (because the feed is only updated once per hour) – so that inches along throughout the hour. For twitter, that one moves a little faster where 100% is 150 seconds (2.5 minutes). Anyhow, I kind of like this. It not only shows me the status of these key things, it shows me the status of when these key things will be updated next!

Next Steps:
First, I’ve tried maybe 5 different POP3 and IMAP .NET components – all open source. They all have at least one major flaw each. 3 outright didn’t work, the others had significant bugs. I need to get that hammered out. Now that I transitioned to gmail, I can now (in theory) use IMAP, which is much more powerful – but also more complicated.

Anyhow, aside from that, the one last thing I’d like to do is make this all configurable. Right now, much of the settings are hard-coded. For example, the URL for the weather for my town, my authorization code for twitter, and the credentials for getting mail are all hard-coded at the moment. Instead, I’d obviously like to have those be user settable.

How I plan to approach that is as follows. Since each user control (twitter, mail, time, and weather) are completely self-sufficient, and since they control their own screen real estate, I could just put the config settings IN the place where the control is. For example for weather – if the current user hasn’t chosen a location, instead of showing all that information, maybe that area of the screen just has a city dropdown, and "Save" button. When they click save, then the control shows what’s up there now. Same for twitter, email, etc. The core settings would be set, in the existing space. You could alter those settings maybe with a little button or icon in the top-right of each control. At least, that’s what I have in my head. That would really be the last step where I could then actually share this source code. I’ve talked to several other developers about this, and this is simple enough, but also complete enough to be a decent reference-architecture application to show how to do MVVM with WPF. So ultimately, I’d like to finish cleaning it up and then share the source.

That’s it for now. Once I get the mail piece straightened out – and maybe if I can figure out how to make these sections user-configurable, I will clean up the project a bit, do some documentation and I’ll post back with my final lessons learned on it. That probably won’t be for a week or more, but that’s the goal…

Tagged with: , ,
Posted in Uncategorized, WPF and MVVM
6 comments on “WPF/MVVM Status app: Update 1
  1. […] This post was mentioned on Twitter by Larry King, Rob Seder. Rob Seder said: WPF/MVVM Status app: Update 1: http://wp.me/p16SsF-8g […]

    Like

  2. Davide says:

    Very good works !! I like it 🙂
    Could you share the code ? I will very appreciate because I’m interested to find out how MVVM pattern works.
    Thanks, D.

    Like

  3. Rob Seder says:

    Davide,
    I do plan to. Right now, the twitter, e-mail, and weather information is hard-coded. I need to make some screens so those are configurable. Once that is done, I will post the code somewhere. With school being pretty heavy at the moment, this probably won’t be for several weeks though. If you have any specific questions though, feel free to shoot me an e-mail at sederrob at gmail dot com. Thanks!
    -Rob

    Like

  4. rajmundr says:

    I appreciate your tireless efforts to get the sorted observable collection worked out 🙂 I would bet it was not that necessary and time spent on it was not the best choice. Since you’d agree in MVVM the displaying of sorted items is a UI thingy, then you’d completely not care about it in the code behind, right? It’s only the matter of knowing how to do that. I mean when you work with your collection in code behind (eg. adding items) you really don’t need to worry about sorting. Let the UI do it through appropriate objects and bindings designed to just do that. Let’s introduce a… CollectionViewSource. Please refer to the link below (scroll down or find “CollectionViewSource”) not only how to set it up in XAML (hence declaratively), but also as a handy reference how to declare collections and arrays in XAML in various ways (very useful for hardcoded choice lists like state abbreviations, etc.). I encourage you to try that and let us know.

    – Add the following resource


    – Modify the Binding of the ListBox

    Like

  5. rajmundr says:

    I don’t know why embedded HTML tags did not work. Here is a try without HTML.

    http://www.wpfwiki.com/Default.aspx?Page=WPF%20Q16.1

    Like

  6. rajmundr says:

    What I have to o to embed sample code? If that also comes blank below I give up.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 4 other followers

%d bloggers like this: