This post assumes you’ve gone through the process of setting up the permissions for a Facebook app and getting your user to log into Facebook through your app. In short, it assumes you’ve walked through this tutorial.
For this tutorial, I’ve re-jiggered the code into a more formal MVVM structure. I’m using MVVM Light because I am familiar with it. I would highly recommend it.
Download Facebook Message in Windows Phone 7 project files
Make sure you go to the App.xaml.cs file to change the FacebookAppID and FacebookAppSecret to fit your particular needs.
This is a full-featured tutorial, running through the view model and view setup for properly sending a Facebook message. If you just want to see the code for sending the message, skip down to “Sending the Facebook Message” at the bottom.
Setting Up Our Properties
Doing this the MVVM way is actually pretty simple. We’ll set up some properties in our view model and use those properties to drive our UI.
We will need:
FacebookMessage – string – This will hold the string message we want to post to Facebook.
IsLoadingMessage – bool – We’ll turn this on when the message is sending and turn it off when we’re done.
SendFacebookMessage – ICommand – We’ll execute this command when we’re ready to send the message out.
Setting Up Our UI
Again, very simple. We are going to add a ScrollViewer (I like to use ScrollViewers whenever the user might be typing so they can still see other bits of the screen) and put the rest of the stuff in there. We’ll add:
1: <TextBox TextWrapping="Wrap"
2: Text="{Binding FacebookMessage, Mode=TwoWay}"
3: MinHeight="175"/>
We want the text to be bound to the message we’re going to send and the TwoWay mode makes sure that any updates we make in the UI are automatically synced with the view model property. I’m using a MinHeight as a way of implying to the user that this could be a multi-line message. Basically just prepping them for what kind of interaction to expect.
1: <Button Content="post to wall"/>
We’ll use this button to run the command that starts all the work. The super-awesome way to do this is to go to the “Assets” tab in the top left corner of the screen, select “Behaviors” and drag an “EventToCommand” behavior onto your button.
select the EventToCommand behavior on the button and you should see on the right properties that can be set on that behavior. Click on the “Advanced options” (the little gray box next to the Command property”) and select “Data Binding”.
The Create Data Binding window will pop up. If you don’t see your command in the fields section, rebuild your project from Blend (under the Project menu) and it should refresh.
Select the SendFacebookMessage command and double check to see that the “EventName” is set to “Click”.
That should be the default, but it’s good to make sure.
Finally, we’re going to put together some UI for the user to get some feedback while the app is updating Facebook. We want two things:
- Not hit the button several times or change the message while it’s updating. In general, just leave everything alone.
- See that an update is happening.
In this project I did this very simply. First, I added some UI to cover all the elements (named “InteractionBlocker”).
1: <Grid x:Name="InteractionBlocker"
2: Grid.Row="1"
3: Margin="0,48,0,0"
4: Background="#97000000"
5: Visibility="{Binding IsLoadingMessage, Converter={StaticResource BoolToVis}}"
6: />
When a message is updating, this grid simply covers the elements. It is semi-transparent, so the UI just goes a little dark while the update is being made. I’m using a BoolToVis converter, which can be used in a binding to convert a boolean value into a visibility value. Here is Kent Boogaart’s version of it, which isn’t the version I use, but works great none-the-less. (My version is in the project if you’re really interested.)
To let the user know that an update is going on, we’ll use a ProgressBar.
1: <ProgressBar
2: Margin="0,4,0,0"
3: Grid.Row="1"
4: VerticalAlignment="Top"
5: Visibility="{Binding IsLoading, Converter={StaticResource BoolToVis}}"
6: IsIndeterminate="{Binding IsLoading}"
7: />
Here, we just set it to crawl across the top of the screen when we’re loading our message. We hide it and show it based on whether the user needs to see it. Pretty simple. (If you’re working on a big Windows Phone project, download and install the Silverlight Toolkit, which has a Progress bar that plays much nicer with your app performance. The default ProgressBar is good enough for our current needs.)
Sending the Facebook Message
We’ll do all our calls in the ICommand we’ve set up. When the user logged in, we created a private FacebookClient object with our access token, so we’ll just go ahead and use that.
1: public ICommand SendFacebookMessage
2: {
3: get { return new RelayCommand(() => {
4: var parameters = new Dictionary<string, object>
5: {
6: {"message", FacebookMessage},
7: {"privacy", new Dictionary<string, object>
8: {
9: {"value", "ALL_FRIENDS"}
10: }
11: }
12: };
13: _asyncFbClient.PostCompleted += new System.EventHandler<FacebookApiEventArgs>(_asyncFbClient_PostCompleted);
14: _asyncFbClient.PostAsync("me/feed", parameters);
15: Deployment.Current.Dispatcher.BeginInvoke(() =>
16: {
17: IsLoadingMessage = true;
18: });
19: });
20: }
21: }
What we’ve done here is set up our command so that we create the appropriate parameters for a normal boring old Facebook message, set up the acync callback so we actually get something and then, finally, jump over to the UI thread so the IsLoadingMessage property bindings make our UI do what we want.
So all we need to do now is handle the response from our post. We’ll do that with the following callback.
1: void _asyncFbClient_PostCompleted(object sender, FacebookApiEventArgs e)
2: {
3: if (!e.Cancelled && e.Error == null)
4: {
5: _asyncFbClient.PostCompleted -= _asyncFbClient_PostCompleted;
6: Deployment.Current.Dispatcher.BeginInvoke(() =>
7: {
8: IsLoadingMessage = false;
9: FacebookMessage = "";
10: });
11: }
12: else
13: {
14: Deployment.Current.Dispatcher.BeginInvoke(() =>
15: {
16: IsLoadingMessage = false;
17: });
18: }
19: }
Here we’ve handled the response. If we wanted to be thorough, we’d catch any cancellations or errors in an else and display the results. But in this simple case, it either works and we’re all happy or it doesn’t work and the user is confused because the only indication that it didn’t work is that the FacebookMessage remains unchanged. On the bright side, they can always hit the “send message” button again and give it another try.