Click here to Skip to main content
Click here to Skip to main content

SongBird - a Twitter Hybrid Smart Client

By , 18 Jun 2009
 
Prize winner in Competition "Smart Client Article Contest"

Background

I've recently been using Microsoft's WCF REST starter kit to access information over the web, and have been very impressed with its ease of use and design, but I wanted more. I didn't want to evaluate the toolkit against a noddy little application that I'd thrown together. I wanted to test it against a busy system; one which was getting thousands of hits a second; one which would really test it to see if it was worth the free asking price.

In order to test out the functionality that Microsoft is providing, I decided to write an application against a source of data that provides a fairly full and feature rich RESTful API. To that end, I've developed a simple Twitter client that allows you to view your latest posts: the latest posts that have been made to Twitter, and the latest posts that your friends have made to Twitter. As well as doing this, it also allows you to upload new messages.

The resulting application is called SongBird, just because I think it's prettier for birds to sing than Tweet (sorry, I know it's a bad pun, but I liked it).

Why REST?

You may be wondering why there's a need for RESTful services. After all, there's a perfectly serviceable means to perform operations over HTTP called SOAP. To get a feel for this, it's important to understand some of the key principals of REST.

  1. Complex operations are represented via a URI.
  2. Representations can be cached.
  3. No state is maintained on the server.
  4. Does not require the consuming systems to be aware of any other architectures than XML and HTTP. In other words, you do not have to implement a full SOAP Web-Service architecture to use REST.
  5. REST is a lightweight format that uses standard HTTP Verbs (PUT, GET, POST, DELETE).

As you can see, if your application needs to perform simple operations, REST is a good choice - especially as you can test your commands in the browser address bar and email them to your friends as links. If your application needs to perform more complex operations, such as updating a master object with lots of sub objects, then REST is not going to be the best choice for this.

The services we are going to use to access Twitter are provided via a RESTful API, which are fairly well documented at http://apiwiki.twitter.com/Twitter-API-Documentation. The API supports a wide variety of MIME type encodings, so it's easy to find a format that suits our needs. It's very important that you read the API documentation for each API call to find out what these types are (known as Formats in Twitter), and to identify the HTTP operations that apply. For instance, if you want to search Twitter using ATOM, you would use http://search.twitter.com/search.atom. As always, the API documentation should also tell you what parameters need passing and how they should be formatted.

REST in SongBird

In order to write SongBird, I decided to use the WCF REST Starter Kit which is currently at Preview 2 status. For the purposes of SongBird, I was happy to use a library that hadn't officially been released yet, and which may undergo some changes before it is finally released. For the purposes of SongBird, it's unlikely that the elements of the component are likely to undergo any serious revisions.

Architecture

Not surprisingly, for those who know me, I have written SongBird using WPF. I have a long history of loving WPF, and use it in pretty much everything that I write now. The interface to SongBird was quickly pulled together using a combination of Visual Studio 2008 and Expression Blend 2. Internally, SongBird makes heavy use of two patterns: Model Model ViewModel (MVVM) and Mediator. I'm not going to go into MVVM in too much depth, except to show how it helped in writing SongBird - if you want to know more about it, please read Josh Smith's, Karl Shifflett's, and Sacha Barber's excellent articles on MVVM. The Mediator pattern is used to relay messages backwards and forwards between Views (well, strictly speaking, it's between ViewModels and not Views).

The themes in SongBird come from the WPFThemes project on CodePlex, and I've also made fairly heavy use of David Anson's excellent BackgroundTaskManager class to neaten up my background tasks.

The screens

When SongBird starts up, the user is presented with the following screen:

StartupScreen.png

The only thing the user can do is enter their account name and password, and minimize or close the window. The portion of the screen at the bottom (the status portion) is disabled, and the posts tabs are hidden until the user has been authenticated. When the user types in their account name and password, the Log in button becomes enabled. This is all accomplished through simple two way databinding and the judicious use of ICommand to wire up commands. The code for the login screen is found in ViewModel/LoginViewModel.cs in the solution.

When the user clicks Log in, SongBird kicks the login process off on a background thread, like so:

private void SignInExecute(object parameter)
{
    try
    {
        string accountName = AccountName;
        string password = Password;
        bool rememberMe = RememberMe;
        Mouse.OverrideCursor = Cursors.Wait;
        LoginMessage = string.Empty;
        BackgroundTaskManager.RunBackgroundTask(() => { return Login(); },
        (result) =>
        {
            Mouse.OverrideCursor = null;
            if (result == null)
            {
                Mediator.Instance.NotifyColleagues(
                   ViewModelMessages.UserAuthenticated, false);
                LoginMessage = "Unfortunately, Twitter did not recognise" + 
                               " this username and " +
                               "password. Please try again";
            }
            else
            {
                LoginResult(result as XElement);
            }
        }
        );
    }
    catch
    {
        LoginMessage = "We are sorry, SongBird was unable" + 
                       " to connect to Twitter. " +
                       "Please check yournetwork connection and try again.";
    }
}

private XElement Login()
{
    try
    {
        return new LoginManagement().Login(AccountName, Password);
    }
    catch (ArgumentOutOfRangeException ex)
    {
        LoginMessage = "We are sorry, SongBird was unable" + 
                       " to connect to Twitter. " +
                       "Please check your network connection and try again.";
    }
    return null;
}

private void LoginResult(XElement root)
{
    SaveDetails("AccountName", AccountName);
    SaveDetails("Password", Password);
    SaveDetails("RememberMe", RememberMe);
    LoginMessage = "You were successfully logged in.";
    Mediator.Instance.NotifyColleagues(ViewModelMessages.UserAuthenticated, true);
}
private void SaveDetails(string key, object value)
{
    App.Current.Properties.Remove(key);
    App.Current.Properties.Add(key, value);
}

The SignInExecute method is triggered by the command associated with the Log in button. It starts off by changing the mouse cursor to the wait cursor, before it creates a background login task. If the log in completes successfully, then the user is informed of this and the Mediator notifies all of the interested ViewModels (I'll shorten this to VMs from now on in) that the user has been successfully authenticated. Note that we save the account name, password, and the remember me flag to the application properties bag so that we can use them in other VMs with ease. So, how does the login actually work?

If you remember, we said earlier that REST uses the URL to communicate. There is a little bit more to this, and this is where the WCF REST starts to provide us with that little bit more support than writing our own code would. As you can imagine, it would not be secure to pass the account name and password as a querystring parameter. Instead, we need to set up some credentials that get passed with the REST request. What we need to do is create an instance of an HttpClient object and give it some credentials -the account name and password that the user has supplied. HttpClient is a utility class designed to manipulate the request and response objects in a much easier, more natural way. We're only going to scratch the surface of HttpClient here, as it provides a lot more power than we need to communicate with the Twitter API. The actual login object looks like the following:

private const string BASEADDRESS = "http://twitter.com/account/";
private const string VERIFYCREDENTIALS = "verify_credentials.xml";
public XElement Login(string accountName, string password)
{
    using (HttpClient client = new HttpClient(BASEADDRESS))
    {
        client.TransportSettings.Credentials = new NetworkCredential(accountName, 
            password);
        using (HttpResponseMessage response = client.Get(VERIFYCREDENTIALS))
        {
            response.EnsureStatusIsSuccessful();
            return response.Content.ReadAsXElement();
        }
    }
}

When we create the HttpClient object, we need to give it a base address for our operations. Again, the Twitter API comes to our rescue, and we find that user verification is present at http://twitter.com/account/verify_credentials.xml. (If we wanted to use a different encoding (such as JSON), we could, but we are going to use XLinq to query the information returned by this request.) The account name and password are supplied as credentials to the HttpClient TransportSettings.

Our code is going to attempt the authentication using the GET verb. HttpClient makes this simple by providing the Get method, and we provide the location of the operation we want to perform here as a parameter to the method. Cunningly enough, other Verbs are named in a similar meaningful fashion, so a PUT is Put, and a POST is Post.

A feature of the WCF REST implementation that I really like is its provision of the EnsureStatusIsSuccessful method, and I heartily recommend that you include this in all of your requests. Basically, this method ensures that the application receives a HTTP Status 200, and throws an exception if it doesn't. This is a quick and convenient way to ensure that the application successfully connects to the target.

Finally, we retrieve the content from the response (inside a HttpResponseMessage) and return it as an XElement object.

At this point, assuming that the user has successfully been authenticated, the mediator has notified interested VMs that the UserAuthenticated is set to true. This causes the posts tabs to be displayed, and the update status area to be enabled.

FriendsScreen.png

The images have been blurred to preserve the anonymity of the posters.

The code to read the posts again runs on a background thread. This VM provides a bit more functionality because it sets SongBird to reread posts every 5 minutes, or when the users update their status. Again, the VMs don't need to know about each other's existence because the Mediator will notify this code that it needs to reread the posts - it's a simple but very powerful mechanism, and one that I recommend that you take a good look at.

protected override void Initialize()
{
    base.Initialize();
    Mediator.Instance.Register((object o) => { 
        ReadTwitter();
        _timer = new Timer(300000); // 5 minute refresh interval
        _timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        _timer.Enabled = true;
        _timer.Start();
    }, ViewModelMessages.UserAuthenticated);
    Mediator.Instance.Register((object o) =>
    {
        _timer.Stop();
        ReadTwitter();
        _timer.Start();
    }, ViewModelMessages.StatusUpdated);
}

The code to actually read the posts is:

private void ReadTwitter()

{
    try
    {
        _accountName = App.Current.Properties["AccountName"].ToString();
        _password = App.Current.Properties["Password"].ToString();
        Mouse.OverrideCursor = Cursors.Wait;
        BackgroundTaskManager.RunBackgroundTask(() => { return DoReadTwitter(); },
          (posts) =>
          {
            Mouse.OverrideCursor = null;
            List<PostItemModel> postItems = new List<PostItemModel>();
            if (posts != null && posts.Count() > 0)
            {
              // Read through the posts and update them...
              foreach (TwitterPost post in posts)
              {
                postItems.Add(PostItemModel.Fill(post));
              }
              Model.Clear();
              Model.AddRange(postItems);
            }
          }
        );
    }
    catch (Exception)
    {
    }
}

The method to read Twitter is set up in a similar way to the method that verifies the user credentials. What quickly becomes apparent, is how well thought out the design actually is, and how easy the consumption of REST services actually is:

private static List<TwitterPost> RetrieveStatuses(string accountName, 
        string password, string location)
{
    List<TwitterPost> posts = new List<TwitterPost>();
    using (HttpClient client = new HttpClient(BASEADDRESS))
    {
        client.TransportSettings.Credentials = 
          new NetworkCredential(accountName, password);
        using (HttpResponseMessage response = client.Get(location))
        {
            response.EnsureStatusIsSuccessful();
            XElement root = response.Content.ReadAsXElement();
            var statuses = root.Descendants("status");
            foreach (XElement status in statuses)
            {
                posts.Add(TwitterPost.Fill(status));
            }
        }
    }
    return posts;
}

When the posts are being read and added to our collection for display with the aid of our ViewModel, we don't want to reread the same image over and over. The image information is returned as part of the XML from the status as a profile URL. We use this URL to retrieve the image using the following helper class:

public static class ImageManager
{
    private static Dictionary<string, BitmapImage> 
    _profileImages = new Dictionary<string,BitmapImage>();
    
    public static BitmapImage GetImage(string key)
    {
        return _profileImages[key];
    }
    
    public static void AddImage(string key)
    {
        if (!_profileImages.ContainsKey(key))
        {
            _profileImages.Add(key, new BitmapImage(new Uri(key)));
        }
    }
}

With the aid of this, our posts bind to the image by retrieving the BitmapImage that maps to the relevant profile URL.

Finally, we have the update status code. Again, this executes on a background thread, and it raises the StatusUpdated notification from the Mediator, informing the posts VMs that they need to update.

The interesting thing behind the HttpClient scenes here is the provision of a handy method to encode the status text for passing as a parameter. In our code, we wrap the status text post with Uri.EscapeUriString to encode the text.

Points of interest

SongBird makes use of a couple of helpers that I've blogged about in the past. There's an implementation of a bulk loadable ObservableCollection, and a databound PasswordBox attached property that you are free to use as you see fit.

Compilation note

You may receive the exception "Error 5 The tag 'VisualStateManager.VisualStateGroups' does not exist in XML namespace 'clr-namespace:System.Windows;assembly=WPFToolkit'. Line 67 Position 38. Theme.xaml 67 38 SongBird" when you compile SongBird. This is a problem with the WPFToolKit DLL and you can safely ignore it. SongBird will still compile safely, and Visual Studio seems to ignore this error.

Finally

SongBird started off as a simple intellectual exercise aimed at testing how the WCF REST functionality stands up to higher load sites, and has impressed me with the ease of development it provides. The question has become - am I finished with SongBird?

Currently, SongBird does the things I do with Twitter, but it could do so much more. If there is sufficient interest in it, if people think it has potential as a Twitter client, then I would look to formalise the development of SongBird and implement some of the features such as friends management and turn SongBird into a fully featured Twitter client.

What do you think? It's up to you.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Pete O'Hanlon
CEO
United Kingdom United Kingdom
A developer for more years than I care to remember. I live in the North East of England with 2 wonderful daughters and a wonderful wife.
 
I am not the Stig, but I do wish I had Lotus Tuned Suspension.
Follow on   Twitter   Google+

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 1memberzyboz5-May-11 6:11 
not sure how this voting works but the code in tehs ample is not what I would call very professional
GeneralRe: My vote of 1mvpPete O'Hanlon10-May-11 10:20 
Sorry Bill, but the hamsters are onto your sockpuppet account. Had you not posted the obviously fake "you are a genius" posting on your own articles (that was just too much), you'd probably have get away with it. Nice try though.

Forgive your enemies - it messes with their heads

My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility


GeneralCan't log in with the applicationmemberdhjoubert@gmail.com24-Mar-11 22:58 
Hi, I downloaded the code compiled it and it ran, but I can't get it to log in with my username and password.   Has anyone else had this problem?   Has the twitter API changed?
GeneralRe: Can't log in with the applicationmemberMichaelTyrer20-Jul-11 9:45 
Yes, I've just had the same problem. I downloaded the executable and have the same problem with that. I'm new to twitter development so I can't say what is wrong.
If anyone finds out what's gone wrong I'd appreciate it.
GeneralRe: Can't log in with the applicationprotectorPete O'Hanlon20-Jul-11 11:30 
Unfortunately, since I wrote this article, Twitter have extensively changed their API.

Forgive your enemies - it messes with their heads

My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility


GeneralRe: Can't log in with the applicationmemberMichaelTyrer21-Jul-11 9:53 
Thanks for the update. At least I know it's not me or my setup.
GeneraltypomvpLuc Pattyn8-Mar-10 1:44 
Hi Pete,
 
I haven't read it yet (just scanned it for Mediator), but I noticed a small typo: Model Model ViewModel (MVVM)
 
Smile | :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]

I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.

GeneralRe: typomvpPete O'Hanlon8-Mar-10 1:58 
You know, you're the first one to notice that (including me). +5 for observational skills.

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



AnswerRe: typomvpLuc Pattyn8-Mar-10 2:14 
just you wait till I actually read your twittering disquisition. Laugh | :laugh:
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]

I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.

GeneralCongratulationmvpAbhijit Jana14-Jul-09 11:30 
Pete, Congratulation and Very well done Smile | :) Thumbs Up | :thumbsup:
 
I have published an article on "Debugging From Remote IIS" . Please have a look. Thanks for the suggestion. Smile | :)
 
cheers,
Abhijit
CodeProject MVP
Web Site:abhijitjana.net
View My Recent Article

GeneralRe: CongratulationmvpPete O'Hanlon14-Jul-09 21:35 
Thanks mate - I shall wander over and have a read immediately.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralRe: Congratulationmembermbaocha25-Aug-09 11:44 
yea. i say thesame. well done pete. this is owesome
 
___________________________________________________
twitter followers |
twitter spamers
GeneralCongratulationsmemberRama Krishna Vavilala13-Jul-09 23:50 
For winning the July Smart Client competition.Beer | [beer]
GeneralRe: CongratulationsmvpPete O'Hanlon14-Jul-09 0:12 
Thanks mate - I didn't expect it.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralGreatmemberDr.Luiji9-Jul-09 20:54 
Wow,
you cover a lot of cool stuff into a single article!!
Good job, you got my 5 stars!
 
NOTE: the name SongBird is already used for an open source music player.
 
Dr.Luiji
 
Trust and you'll be trusted.
 
My Blog : The Code Is Art

GeneralRe: GreatmvpPete O'Hanlon9-Jul-09 21:27 
Thanks a lot for that.
 

Dr.Luiji wrote:
NOTE: the name SongBird is already used for an open source music player.

 
Durn it. I'll have to find another name.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralGreat Articlemembericetea9422-Jun-09 21:02 
Hi, this is a great article, but the name Songbird is already in use. It's an iTunes-like Mozilla application for song management.
But anyway, an interesting article
-
icetea
GeneralRe: Great ArticlemvpPete O'Hanlon22-Jun-09 21:53 
Thanks for that - oh well, as this application grows, I'll have to find another name for it. I'm leaning towards Kingfisher right now, but that's just because it's a beer. Big Grin | :-D
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralGreat Stuff Pete!memberma1achai22-Jun-09 18:32 
You cover a lot of stuff that I'm interested in learning right now... and tearing apart a *good* example is the best way for me to learn, personally.
 
I'd really love to see you expand on the Twitter client and make it a full-blown tweetdeck alternative. Even though I haven't become a twitter addict quite yet, I see tweet clients as having lots of room for improvement... ease of use and features that have yet to be thought of. Would love to watch the evolution of something like that...
 
5 stars, of course... good luck and keep us informed. I'll be following you now...
GeneralRe: Great Stuff Pete!mvpPete O'Hanlon22-Jun-09 21:52 
Thanks for that. I started updating the code last night to provide a fuller featured model, and once I've finished pulling the backend together, I'm going to look at hosting it on Codeplex. I'll let you know.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralGreat PetememberDaniel Vaughan19-Jun-09 23:44 
Pete,
 
This is really cool, and works nicely. I had to try it out. http://twitter.com/vaughandaniel[^]
 
5 stars from me.
 
Cheers,
Daniel
 
Daniel Vaughan
Blog: DanielVaughan.Orpius.com

GeneralRe: Great PetemvpPete O'Hanlon19-Jun-09 23:56 
Thanks Daniel - and now I'm following you Big Grin | :-D
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralRe: Great PetememberDaniel Vaughan20-Jun-09 0:01 
Cool, and I you. Smile | :)
 
Daniel Vaughan
Blog: DanielVaughan.Orpius.com

GeneralWow. There is a lot that can be learned from this article/sample...memberjaime rodriguez19-Jun-09 9:38 
This could have been 3 different articles/topics. on the WPF side, this is great learning tool. Thanks Pete!!
 
Cool | :cool:
GeneralRe: Wow. There is a lot that can be learned from this article/sample...mvpPete O'Hanlon19-Jun-09 9:46 
Thanks. I held off delivering this one until I was happy that it would help people with aspects such as MVVM, Mediator as well as REST.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralExcelent WorkmvpAbhijit Jana19-Jun-09 8:57 
Pete, this is fantastic. Got my 5 Smile | :)
 
cheers,
Abhijit
CodeProject MVP
Web Site:abhijitjana.net
View My Recent Article

GeneralRe: Excelent WorkmvpPete O'Hanlon19-Jun-09 9:08 
Thanks man - I really appreciate it.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralGreat jobmemberWilliam E. Kempf19-Jun-09 5:02 
Got my 5. Nice looking App as well Wink | ;) .
 
William E. Kempf

GeneralRe: Great jobmvpPete O'Hanlon19-Jun-09 5:06 
Thanks Bill. Much appreciated.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



QuestionPerformancememberkamarchand19-Jun-09 2:32 
Hi,
 
You mention that you wanted to test the RESTFull against a busy system.
Can you give us some feedback on your experience of using RESTFull with a buzy system.
 
Thanks
AnswerRe: PerformancemvpKarl Shifflett19-Jun-09 2:56 
Amazon.com pretty fast response for sure.
 
Cheers, Karl
 
» CodeProject 2008 MVP, CodeProject 2009 MVP
 
My Blog | Mole's Home Page |
XAML Power Toys Home Page

Just a grain of sand on the worlds beaches.


AnswerRe: PerformancemvpPete O'Hanlon19-Jun-09 3:47 
Well, I've been impressed by the turnaround of results from Twitter. The datasets aren't large - one of the reasons I chose Twitter to test against, but the speed of them serving data is impressive.
 
To my mind, the fact that I'm not having to marshall data at the client side to transmit, which then needs to be unmarshalled before the real processing can begin has been a real benefit. Added to that, the wide variety of formats that are supported makes this a very attractive solution. I actually found that the WCF REST service responded faster than code I'd previously written to do the same type of processing.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralProblem with one of your graphics.memberDave Lamb18-Jun-09 22:16 
peteohanlon the picture of the posts is blurry. is this a problem with the image classes?
 
nice looking app tho, gets my 5.
GeneralRe: Problem with one of your graphics.mvpPete O'Hanlon18-Jun-09 22:19 
Dave - I blurred the graphic using Photoshop so that anonymity was preserved for posters.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralCannot Compile Project [modified]membersam.hill18-Jun-09 19:49 
Error 5 The tag 'VisualStateManager.VisualStateGroups' does not exist in XML namespace 'clr-namespace:System.Windows;assembly=WPFToolkit'. Line 67 Position 38. Theme.xaml 67 38 SongBird
 
modified on Friday, June 19, 2009 1:55 AM

GeneralRe: Cannot Compile ProjectmvpPete O'Hanlon18-Jun-09 20:29 
That's a problem that's falsely reported by the WpfToolkit dll. You can safely ignore this error and run the application. I'll put a note in the article to that effect.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralRe: Cannot Compile Projectmemberdbmeyer22-Nov-09 8:04 
I'm also seeing the same error, which is being reported identically. (I'm running VS 3.5 SP1, FWIW). Unfortunately, I can't figure out how to take your advice ('You can safely ignore this error and run the application.').
 
Since I can't compile, I can't run.
 
I have also downloaded the executable, which runs very impressively. Now I'm looking forward to getting under the hood and see how the magic is performed.
 
So, in summary, I'm just looking for a workaround to the error. It must be right in front of my nose, but I can't see it.
 
Doug
GeneralRe: Cannot Compile ProjectmvpPete O'Hanlon18-Jun-09 22:04 
Thanks for pointing this out Sam - I've updated the article text to cover this.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralRe: Cannot Compile Projectmembersam.hill19-Jun-09 15:25 
OK, Thanks.
Very innovative app!
GeneralRe: Cannot Compile ProjectmvpPete O'Hanlon21-Jun-09 10:17 
Thanks - I'm glad you like it. In general, the bar has been set very high for WPF apps by the likes of Josh Smith, Karl Shifflett, Sacha Barber and Daniel Vaughan. I didn't want to let them down.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralCool Pete!mvpKarl Shifflett18-Jun-09 17:48 
Hey Pete,
 
Nice work, didn't know about the REST toolkit.
 
I have a Twitter app I want to do also. Maybe after my next two or thee Code Project articles I really need to write.
 
FYI:
 
There is a Network.NetworkAvailabilityChanged Event that you can subscrbe to to track the current state of the computer's network connection.
 
http://msdn.microsoft.com/en-us/library/ms229236(VS.85).aspx[^]
 

We also have a property My.Computer.Network.IsAvailable that can be used to check the status of the network before using it.
 
http://msdn.microsoft.com/en-us/library/d1e9b5cx(VS.80).aspx[^]
 
(yes you have to reference a VB assembly, but it works!)
 
Cheers, Karl
 
» CodeProject 2008 MVP, CodeProject 2009 MVP
 
My Blog | Mole's Home Page |
XAML Power Toys Home Page

Just a grain of sand on the worlds beaches.


GeneralRe: Cool Pete!mvpSacha Barber18-Jun-09 20:47 
Karl Shifflett wrote:
Nice work, didn't know about the REST toolkit.

 
What you didn't read my GeoPlaces : hybrid smart client, involving RESTful WCF/WPF and more[^] article. Ba humbug to you Shifflett.
 
Ha, no its all good baby.
 
Anyway Pete have a 5
 
Sacha Barber
  • Microsoft Visual C# MVP 2008/2009
  • Codeproject MVP 2008/2009
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

GeneralRe: Cool Pete!mvpPete O'Hanlon18-Jun-09 21:27 
Sacha Barber wrote:
Ba humbug to you Shifflett.

 
Laugh | :laugh:
 

Sacha Barber wrote:
Anyway Pete have a 5

 
Cheers mate. Much appreciated - it'll help counter the 3 and 4 votes it's already received.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralRe: Cool Pete!mvpSacha Barber18-Jun-09 22:15 
Pete
 

As part of the code example I am doing for a MVVM demo for the book, Id like to use you "Please Select" CompositeCollectin lovelyness is that ok?
 
Sacha Barber
  • Microsoft Visual C# MVP 2008/2009
  • Codeproject MVP 2008/2009
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

GeneralRe: Cool Pete!mvpPete O'Hanlon18-Jun-09 22:17 
That would be great. Anything you need.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralRe: Cool Pete!mvpSacha Barber18-Jun-09 23:42 
Cheers bud
 
Sacha Barber
  • Microsoft Visual C# MVP 2008/2009
  • Codeproject MVP 2008/2009
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

GeneralRe: Cool Pete!memberJammer18-Jun-09 22:24 
Grrr ... these people are annoying! If your not going to vote 4 or 5 ... explain why!
 

GeneralRe: Cool Pete!mvpPete O'Hanlon18-Jun-09 22:32 
My suspicion is that it was to get me off the "best picks" bit of the homepage. Oh well.
 
To be honest, I was hoping for more opinion on whether or not people wanted SongBird to be expanded to be a more feature rich Twitter app.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralRe: Cool Pete!mvpKarl Shifflett19-Jun-09 2:55 
Dr. Sacha,
 
Read your splendid thesis on RESTful ...
 
Cheers, Karl
 
» CodeProject 2008 MVP, CodeProject 2009 MVP
 
My Blog | Mole's Home Page |
XAML Power Toys Home Page

Just a grain of sand on the worlds beaches.


GeneralRe: Cool Pete!mvpPete O'Hanlon18-Jun-09 21:55 
Karl Shifflett wrote:
FYI:
 
There is a Network.NetworkAvailabilityChanged Event that you can subscrbe to to track the current state of the computer's network connection.
 
http://msdn.microsoft.com/en-us/library/ms229236(VS.85).aspx[^]
 

We also have a property My.Computer.Network.IsAvailable that can be used to check the status of the network before using it.
 
http://msdn.microsoft.com/en-us/library/d1e9b5cx(VS.80).aspx[^]
 
(yes you have to reference a VB assembly, but it works!)

 
Thanks for the info Karl, but the EnsureStatusIsSuccessful tells us what response code we got from the server. I like the idea of incorporating the network check at the client side though, to prevent an attempt to update the client if the network connection is down.
 

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130617.1 | Last Updated 19 Jun 2009
Article Copyright 2009 by Pete O'Hanlon
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid