Integrating Facebook in Windows Store Apps Part 2 – Boredom Challenge Day 13

Standard

In my previous article, we’ve seen how we can sign in to Facebook, display our user’s data and share status updates in Windows Store apps. In this article, we will take our example app further by reading and displaying the user’s timeline and allowing the user to like/unlike posts, view a post’s comments and also add comments of his/her own.

1

We’ll start with the part 1’s completed app and continue from there. If you wish to go with the article step by step, you can get it here. If you’d rather not, jump to the end of the article for the completed source code. 😉

In this article, we will see how we can create Json classes for Facebook items, how we can read and display our user’s timeline, how we can like/unlike posts and how we can display and add comments. Apparently we have a lot of work to do.

First, we’ll start by adding “read_stream” permission to our app on Facebook because we’ll need it to read the user’s feeds.

2

Then, open up the previous article’s project in Visual Studio and rename the solution name to FacebookAppV2 to avoid confusion. We’ll make some small changes to prepare our app, by removing the fbAccessToken string in the MainPage.xaml.cs and making it a global variable in App.xaml.cs (and fix the existing code to use this global variable). We also need to add a global userId variable in App.xaml.cs that will keep the user’s Facebook id. They will be needed when liking and posting new comments.

In App.xaml.cs:

        public string fbAccessToken;
        public string userID;

In MainPage.xaml.cs:

string permissions = "user_about_me, user_birthday, user_hometown, publish_stream, read_stream";
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (ApplicationData.Current.LocalSettings.Values["accesstoken"] != null)
            {
                ButtonSignIn.Content = "Sign Out";
                ((App)Application.Current).fbAccessToken = ApplicationData.Current.LocalSettings.Values["accesstoken"].ToString();
                ReadUserInfo();
            }
        }
        private void ButtonSignIn_Click(object sender, RoutedEventArgs e)
        {
            if (ButtonSignIn.Content.ToString() == "Sign In")
            {
                SignInToFacebook();
            }
            else
            {
                ButtonSignIn.Content = "Sign In";
                ((App)Application.Current).fbAccessToken = null;
                ((App)Application.Current).userID = null;
                ApplicationData.Current.LocalSettings.Values.Remove("accesstoken");
            }
        }

In SignInToFacebook()

if (webAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success)
                {
                    ProgressBar.IsIndeterminate = true;
                    ProgressBar.Visibility = Visibility.Visible;
                    Uri callbackUri = new Uri(webAuthenticationResult.ResponseData.ToString());
                    FacebookOAuthResult facebookOauthResult = facebookClient.ParseOAuthCallbackUrl(callbackUri);
                    string accessToken = facebookOauthResult.AccessToken;
                    if (!String.IsNullOrEmpty(accessToken))
                    {
                        dynamic longaccesstoken = await facebookClient.GetTaskAsync("oauth/access_token?grant_type=fb_exchange_token&client_id=" +
                                                         facebookAppId + "&client_secret=" + facebookAppSecret +
                                                         "&fb_exchange_token=" + accessToken);
                        ((App)Application.Current).fbAccessToken = longaccesstoken.access_token;
                        ApplicationData.Current.LocalSettings.Values["accesstoken"] = ((App)Application.Current).fbAccessToken;
                        ButtonSignIn.Content = "Sign Out";
                        ReadUserInfo();
                        ButtonSignIn.IsEnabled = true;
                        ProgressBar.Visibility = Visibility.Collapsed;
                        ProgressBar.IsIndeterminate = false;
                    }
                }
        async private void ReadUserInfo()
        {
            try
            {
                ProgressBar.IsIndeterminate = true;
                ProgressBar.Visibility = Visibility.Visible;
                dynamic userInfo = await facebookClient.GetTaskAsync("me?access_token=" + ((App)Application.Current).fbAccessToken);
                ((App)Application.Current).userID = userInfo.id;
                ImageUser.Source = new BitmapImage(new Uri(String.Format("https://graph.facebook.com/{0}/picture?type=large", userInfo.id)));
                TextBlockUserName.Text = userInfo.name;
                TextBlockGender.Text = userInfo.gender;
                TextBlockBirthday.Text = userInfo.birthday;
                TextBlockHometown.Text = userInfo.hometown.name;
                ProgressBar.Visibility = Visibility.Collapsed;
                ProgressBar.IsIndeterminate = false;
            }
            catch
            {
                ButtonSignIn.IsEnabled = true;
                ProgressBar.Visibility = Visibility.Collapsed;
                ProgressBar.IsIndeterminate = false;
                MessageDialog messageDialog = new MessageDialog("The internet has been deleted. There is no Facebook any more. Sorry.");
                messageDialog.ShowAsync();
            }
        }
        async private void ButtonPost_Click(object sender, RoutedEventArgs e)
        {
            if (((App)Application.Current).fbAccessToken != null)
            {
                try
                {
                    var postparameters = new
                    {
                        access_token = ((App)Application.Current).fbAccessToken,
                        message = TextBoxPost.Text
                    };
                    dynamic result = await facebookClient.PostTaskAsync("me/feed", postparameters);
                    MessageDialog messageDialog = new MessageDialog("Post successful, check your Facebook page. :)");
                    await messageDialog.ShowAsync();
                }
                catch
                {
                    MessageDialog messageDialog = new MessageDialog("The internet has been deleted. There is no Facebook any more. Sorry.");
                    messageDialog.ShowAsync();
                }
            }
            else
            {
                MessageDialog messageDialog = new MessageDialog("Please sign in to Facebook first.");
                await messageDialog.ShowAsync();
            }
        }

Alright then, our app is ready to expand. Now we will create Facebook classes from a Json string. To do this, we’ll use Graph API Explorer tool in Facebook, which allows us to query Graph API for debugging purposes, and http://json2csharp.com/ website which generates C# classes from Json strings.

Open Graph API Explorer by browsing to https://developers.facebook.com/tools/explorer, enter “me/feed” to the textbox (me/feed gets our timeline) and click submit. You may need to give read_stream permission to Graph API Explorer, which can be done by clicking “Get Access Token” and selecting appropriate permissions from the list. It will return a large json string consisting of your timeline items.

3

Now copy that entire Json string, paste it in http://json2csharp.com/ and click Generate.

4

Then we’ll create a .cs file in our project called FacebookClasses and paste the generated classes in it. When you do it however, you’ll notice that names of some of the classes are generic names, like RootObject, Datum1, Datum2 etc.. We’ll need to understand what objects they are and give them more meaningful names. To do this, after pasting, replace the following names: RootObject to FacebookPosts, Datum to FacebookPost, Datum2 to Like, From to User, Datum3 to Comment, Application to FacebookApplication. Also remove From2, Datum4 and Datum5 and use User in their places instead. The resulting classes will look like below.

namespace FacebookApp
{
    public class User
    {
        public string name { get; set; }
        public string id { get; set; }
    }

    public class Action
    {
        public string name { get; set; }
        public string link { get; set; }
    }

    public class Privacy
    {
        public string description { get; set; }
        public string value { get; set; }
        public string friends { get; set; }
        public string networks { get; set; }
        public string allow { get; set; }
        public string deny { get; set; }
    }

    public class FacebookApplication
    {
        public string name { get; set; }
        public string id { get; set; }
        public string @namespace { get; set; }
    }

    public class Like
    {
        public string id { get; set; }
        public string name { get; set; }
    }

    public class Cursors
    {
        public string after { get; set; }
        public string before { get; set; }
    }

    public class Paging
    {
        public Cursors cursors { get; set; }
        public string next { get; set; }
    }

    public class Likes
    {
        public List<Like> data { get; set; }
        public Paging paging { get; set; }
    }

    public class MessageTag
    {
        public string id { get; set; }
        public string name { get; set; }
        public string type { get; set; }
        public int offset { get; set; }
        public int length { get; set; }
    }

    public class Comment
    {
        public string id { get; set; }
        public User from { get; set; }
        public string message { get; set; }
        public bool can_remove { get; set; }
        public string created_time { get; set; }
        public int like_count { get; set; }
        public bool user_likes { get; set; }
        public List<MessageTag> message_tags { get; set; }
    }

    public class Cursors2
    {
        public string after { get; set; }
        public string before { get; set; }
    }

    public class Paging2
    {
        public Cursors2 cursors { get; set; }
    }

    public class Comments
    {
        public List<Comment> data { get; set; }
        public Paging2 paging { get; set; }
    }

    public class To
    {
        public List<User> data { get; set; }
    }

    public class __invalid_type__102
    {
        public string id { get; set; }
        public string name { get; set; }
        public string type { get; set; }
        public int offset { get; set; }
        public int length { get; set; }
    }

    public class MessageTags
    {
        public List<__invalid_type__102> __invalid_name__102 { get; set; }
    }

    public class WithTags
    {
        public List<User> data { get; set; }
    }

    public class Location
    {
        public string street { get; set; }
        public string city { get; set; }
        public string state { get; set; }
        public string country { get; set; }
        public string zip { get; set; }
        public double latitude { get; set; }
        public double longitude { get; set; }
    }

    public class Place
    {
        public string id { get; set; }
        public string name { get; set; }
        public Location location { get; set; }
    }

    public class FacebookPost
    {
        public string id { get; set; }
        public User from { get; set; }
        public string story { get; set; }
        public string picture { get; set; }
        public string link { get; set; }
        public string name { get; set; }
        public string caption { get; set; }
        public string description { get; set; }
        public string icon { get; set; }
        public List<Action> actions { get; set; }
        public Privacy privacy { get; set; }
        public string type { get; set; }
        public string status_type { get; set; }
        public FacebookApplication application { get; set; }
        public string created_time { get; set; }
        public string updated_time { get; set; }
        public Likes likes { get; set; }
        public string message { get; set; }
        public Comments comments { get; set; }
        public string object_id { get; set; }
        public To to { get; set; }
        public MessageTags message_tags { get; set; }
        public WithTags with_tags { get; set; }
        public Place place { get; set; }
        public string source { get; set; }
        public int? height { get; set; }
        public int? width { get; set; }
    }

    public class Paging3
    {
        public string previous { get; set; }
        public string next { get; set; }
    }

    public class FacebookPosts
    {
        public List<FacebookPost> data { get; set; }
        public Paging3 paging { get; set; }
    }
}

There are still some awkwardly named classes but we won’t be needing them, so I left them be. Anyway, having these classes will give us IntelliSense support as well as the benefits of being strongly typed.

Next step, we’ll add Json.NET and Callisto libraries to our project from NuGet. Json.NET is obviously needed for deserialization, and we’ll use the SettingsFlyout control in Callisto for displaying and adding comments.

5

6

One last thing we need to do before building our app is to add VariableSizedGridView from one of my previous blog posts, which we will need to set two differently sized items in the gridview (like you saw in the screenshot at the beginning of the article). To do this, create a new class in the project named VariableSizedGridView and fill it with the code below:

7

using Windows.UI.Xaml.Controls;

namespace FacebookApp
{
    public class VariableSizedGridView : GridView
    {
        protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
        {
            FacebookPost facebookPost = item as FacebookPost;

            int height = 0;
            if (facebookPost.message == null && facebookPost.description == null)
            {
                height = 1;
            }
            else
            {
                height = 2;
            }

            element.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, 1);
            element.SetValue(VariableSizedWrapGrid.RowSpanProperty, height);

            base.PrepareContainerForItemOverride(element, item);
        }
    }
}

Ok, let’s take a break and explain what we are going to do. In MainPage.xaml, we’ll have a GridView which will list the user’s timeline items, and this GridView will have an item template consisting of a custom user control, which will allow us to interact with the posts. We’re using GridView instead of ListView, because in my experience ListView encountered some binding problems with custom user controls that caused inconsistent behaviour, when there were more than 9-10 items (probably because of loading new items and unloading old items when scrolling). Anyway, let’s create our custom user control named FacebookPostUserControl and create its interface:

8

    <Grid x:Name="GridRoot" Background="#FF4351A1" Width="400" Height="340" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Image x:Name="ImageUser" HorizontalAlignment="Left" Height="100" Margin="10,10,0,0" VerticalAlignment="Top" Width="100"/>
        <TextBlock HorizontalAlignment="Left" Margin="115,10,0,0" Text="{Binding from.name}" VerticalAlignment="Top" FontFamily="Segoe UI" FontSize="17" Width="275" TextTrimming="WordEllipsis" FontWeight="Light"/>
        <TextBlock HorizontalAlignment="Left" Margin="115,37,0,0" Text="{Binding story}" VerticalAlignment="Top" FontFamily="Segoe UI" FontSize="15" Width="275" TextTrimming="WordEllipsis" FontWeight="Light" Height="75" TextWrapping="Wrap"/>
        <TextBlock x:Name="TextBlockMessage" HorizontalAlignment="Left" Margin="10,115,0,0" Text="{Binding message}" VerticalAlignment="Top" FontFamily="Segoe UI" FontSize="15" Width="380" TextTrimming="WordEllipsis" FontWeight="Light" TextWrapping="Wrap" MaxHeight="172"/>
        <TextBlock HorizontalAlignment="Left" Margin="115,62,0,0" Text="{Binding name}" VerticalAlignment="Top" FontFamily="Segoe UI" FontSize="15" Width="275" TextTrimming="WordEllipsis" FontWeight="Light" Height="50" TextWrapping="Wrap"/>
        <TextBlock x:Name="TextBlockDescription" HorizontalAlignment="Left" Margin="10,115,0,0" Text="{Binding description}" VerticalAlignment="Top" FontFamily="Segoe UI" FontSize="15" Width="380" TextTrimming="WordEllipsis" FontWeight="Light" TextWrapping="Wrap" MaxHeight="172"/>
        <Button x:Name="ButtonLike" Content="Like" HorizontalAlignment="Left" Margin="10,0,0,10" VerticalAlignment="Bottom" Width="130" Height="38" Click="ButtonLike_Click" Visibility="Collapsed"/>
        <Button x:Name="ButtonComment" Content="Comments" HorizontalAlignment="Left" Margin="262,0,0,10" VerticalAlignment="Bottom" Height="38" Click="ButtonComment_Click" Width="130" Visibility="Collapsed"/>
    </Grid>

Then we will fill the codebehind file of our user control, FacebookPostUserControl.xaml.cs:

using Windows.UI.Xaml.Media.Imaging;
using Facebook;
using Windows.UI.Popups;
        public FacebookPostUserControl()
        {
            this.InitializeComponent();
            this.Loaded += FacebookPostUserControl_Loaded;
        }

        void FacebookPostUserControl_Loaded(object sender, RoutedEventArgs e)
        {
            FacebookPost post = this.DataContext as FacebookPost;
            ImageUser.Source = new BitmapImage(new Uri(String.Format("https://graph.facebook.com/{0}/picture?type=large", post.from.id)));
            if (post.message == null && post.description == null)
            {
                GridRoot.Height = 160;
            }
            else
            {
                GridRoot.Height = 330;
            }
            if (post.actions != null)
            {
                Action likeAction = post.actions.Where(f => f.name == "Like").FirstOrDefault();
                if (likeAction != null)
                {
                    if (post.likes != null)
                    {
                        Like like = post.likes.data.Where(g => g.id == ((App)Application.Current).userID).FirstOrDefault();
                        if (like != null)
                        {
                            ButtonLike.Content = "Unlike";
                        }
                    }
                    ButtonLike.Visibility = Visibility.Visible;
                }

                Action commentAction = post.actions.Where(h => h.name == "Comment").FirstOrDefault();
                if (commentAction != null)
                {
                    int comments = 0;
                    if (post.comments != null)
                    {
                        comments = post.comments.data.Count();
                    }
                    if (comments == 1)
                    {
                        ButtonComment.Content = "1 Comment";
                    }
                    else
                    {
                        ButtonComment.Content = comments + " Comments";
                    }
                    ButtonComment.Visibility = Visibility.Visible;
                }
            }
            else
            {
                ButtonLike.Visibility = Visibility.Collapsed;
                ButtonComment.Visibility = Visibility.Collapsed;
            }
        }

        async private void ButtonLike_Click(object sender, RoutedEventArgs e)
        {
            FacebookClient facebookClient = new FacebookClient();
            FacebookPost facebookPost = this.DataContext as FacebookPost;
            if (ButtonLike.Content.ToString() == "Like")
            {
                try
                {
                    ButtonLike.Content = "Unlike";
                    var parameters = new
                    {
                        access_token = ((App)Application.Current).fbAccessToken
                    };
                    await facebookClient.PostTaskAsync(facebookPost.id + "/likes", parameters);
                }
                catch
                {
                    ButtonLike.Content = "Like";
                    MessageDialog messageDialog = new MessageDialog("Could not like.");
                    messageDialog.ShowAsync();
                }
            }
            else
            {
                try
                {
                    ButtonLike.Content = "Like";
                    var parameters = new
                    {
                        access_token = ((App)Application.Current).fbAccessToken
                    };
                    await facebookClient.DeleteTaskAsync(facebookPost.id + "/likes?access_token=" + ((App)Application.Current).fbAccessToken);
                }
                catch
                {
                    ButtonLike.Content = "Unlike";
                    MessageDialog messageDialog = new MessageDialog("Could not unlike.");
                    messageDialog.ShowAsync();
                }
            }
        }

Here, in FacebookPostUserControl_Loaded, we determine the height of our item. Since Facebook has many different post types, if our message does not include a description (for a shared link) or a message (for a status), we set our item to be small. Then, if the item is “likable” or “commentable”, we set the visibilities of the like and comment buttons. We also check if our user has already liked it, and also display how many comments the post currently has. And in ButtonLike_Click, we like-unlike the post.

Note that we haven’t prepared the comments page yet. We will create it later, now let’s prepare our MainPage. Add a VariableSizedGridView in MainPage.xaml like the following:

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <ProgressBar x:Name="ProgressBar" VerticalAlignment="Top" Visibility="Collapsed"/>
        <Button x:Name="ButtonSignIn" Content="Sign In" HorizontalAlignment="Left" Margin="100,100,0,0" VerticalAlignment="Top" Width="93" Click="ButtonSignIn_Click"/>
        <Image x:Name="ImageUser" HorizontalAlignment="Left" Height="150" Margin="100,143,0,0" VerticalAlignment="Top" Width="150"/>
        <TextBlock x:Name="TextBlockUserName" HorizontalAlignment="Left" Margin="100,298,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="15"/>
        <TextBlock x:Name="TextBlockGender" HorizontalAlignment="Left" Margin="100,321,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="15"/>
        <TextBlock x:Name="TextBlockBirthday" HorizontalAlignment="Left" Margin="100,344,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="15"/>
        <TextBlock x:Name="TextBlockHometown" HorizontalAlignment="Left" Margin="100,367,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="15"/>
        <TextBox x:Name="TextBoxPost" HorizontalAlignment="Left" Margin="507,143,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="150" Width="400"/>
        <Button x:Name="ButtonPost" Content="Post Status" HorizontalAlignment="Left" Margin="507,298,0,0" VerticalAlignment="Top" Click="ButtonPost_Click"/>
        <local:VariableSizedGridView x:Name="GridViewTimeline" Margin="0,390,0,50" Padding="100,0,0,0">
            <GridView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <local:FacebookPostUserControl />
                    </Grid>
                </DataTemplate>
            </GridView.ItemTemplate>
            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <VariableSizedWrapGrid Orientation="Vertical" ItemHeight="170" ItemWidth="410"/>
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>
        </local:VariableSizedGridView>
    </Grid>

Then, to show the items, add the code in MainPage.xaml.cs that gets the user’s timeline:

using Newtonsoft.Json
        async private void ReadUserInfo()
        {
            try
            {
                ProgressBar.IsIndeterminate = true;
                ProgressBar.Visibility = Visibility.Visible;
                dynamic userInfo = await facebookClient.GetTaskAsync("me?access_token=" + ((App)Application.Current).fbAccessToken);
                ImageUser.Source = new BitmapImage(new Uri(String.Format("https://graph.facebook.com/{0}/picture?type=large", userInfo.id)));
                ((App)Application.Current).userID = userInfo.id;
                TextBlockUserName.Text = userInfo.name;
                TextBlockGender.Text = userInfo.gender;
                TextBlockBirthday.Text = userInfo.birthday;
                TextBlockHometown.Text = userInfo.hometown.name;
                ReadUserTimeline();
                //ProgressBar.Visibility = Visibility.Collapsed;
                //ProgressBar.IsIndeterminate = false;
            }
            catch
            {
                ButtonSignIn.IsEnabled = true;
                ProgressBar.Visibility = Visibility.Collapsed;
                ProgressBar.IsIndeterminate = false;
                MessageDialog messageDialog = new MessageDialog("The internet has been deleted. There is no Facebook any more. Sorry.");
                messageDialog.ShowAsync();
            }
        }

        async private void ReadUserTimeline()
        {
            try
            {
                ProgressBar.IsIndeterminate = true;
                ProgressBar.Visibility = Visibility.Visible;
                string resultString = (await facebookClient.GetTaskAsync("me/feed?access_token=" + ((App)Application.Current).fbAccessToken)).ToString();
                FacebookPosts facebookPosts = JsonConvert.DeserializeObject<FacebookPosts>(resultString);
                GridViewTimeline.ItemsSource = facebookPosts.data;
                ProgressBar.Visibility = Visibility.Collapsed;
                ProgressBar.IsIndeterminate = false;
            }
            catch
            {
                MessageDialog messageDialog = new MessageDialog("Could not get user timeline.");
                messageDialog.ShowAsync();
            }
        }

You can see that getting a user’s timeline is as easy as reading the user’s information, we just send our request to “me/feed” instead. We can also send the request to “me/home” to read user’s news feed (main page). Let’s run the app now and see how it looks.

9

Well, not bad. I know the interface looks weird but that is not important here anyway. You can try liking – unliking and check if it works on Facebook. 🙂

The last thing we need to add is showing the comments and allowing the user to post comments. To do this, we’ll use SettingsFlyout control from Callisto, which needs its content to be set as a user control. So we will create another user control, which we’ll use to list the comments, name it CommentsPageUserControl, and fill it’s interface and codebehind file like shown below:

10

In CommentsPageUserControl.xaml:

    <StackPanel>
        <ListView x:Name="ListViewComments" Margin="0" MaxHeight="600">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Background="#FF4351A1" Width="550">
                        <TextBlock x:Name="TextBlockUserName" Margin="10,10,10,0" Text="{Binding from.name}" VerticalAlignment="Top" FontFamily="Segoe UI" FontSize="18" TextTrimming="WordEllipsis" FontWeight="Light" Foreground="White"/>
                        <TextBlock x:Name="TextBlockMessage" Margin="10" Text="{Binding message}" VerticalAlignment="Top" FontFamily="Segoe UI" FontSize="15" TextTrimming="WordEllipsis" FontWeight="Light" Foreground="White" TextWrapping="Wrap"/>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <TextBox x:Name="TextBoxComment" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0" Height="104" Width="580" AcceptsReturn="True" TextWrapping="Wrap"/>
        <Button x:Name="ButtonComment" Content="Send Comment" HorizontalAlignment="Left" VerticalAlignment="Stretch" Margin="10,10,0,0" Click="ButtonComment_Click"/>
    </StackPanel>

In CommentsPageUserControl.xaml.cs:

using Facebook;
using Windows.UI.Popups;
        public CommentsPageUserControl()
        {
            this.InitializeComponent();
            this.Loaded += CommentsPageUserControl_Loaded;
        }

        void CommentsPageUserControl_Loaded(object sender, RoutedEventArgs e)
        {
            FacebookPost facebookPost = this.DataContext as FacebookPost;
            if (facebookPost.comments != null)
            {
                ListViewComments.ItemsSource = facebookPost.comments.data;
            }
        }

        async private void ButtonComment_Click(object sender, RoutedEventArgs e)
        {
            ButtonComment.IsEnabled = false;
            FacebookPost facebookPost = this.DataContext as FacebookPost;
            FacebookClient facebookClient = new FacebookClient();
            try
            {
                var parameters = new
                {
                    access_token = ((App)Application.Current).fbAccessToken,
                    message = TextBoxComment.Text
                };
                await facebookClient.PostTaskAsync(facebookPost.id + "/comments", parameters);
                MessageDialog messageDialog = new MessageDialog("Comment successfully posted, check Facebook to see it. :)");
                await messageDialog.ShowAsync();
            }
            catch
            {
                MessageDialog messageDialog = new MessageDialog("Could not post comment.");
                messageDialog.ShowAsync();
            }
        }

And finally, we’ll just set the click event of the comment button in FacebookPostUserControl:

using Callisto.Controls;
using Windows.UI;
        private void ButtonComment_Click(object sender, RoutedEventArgs e)
        {
            var flyout = new SettingsFlyout();
            CommentsPageUserControl commentsPage = new CommentsPageUserControl();
            commentsPage.DataContext = this.DataContext;
            flyout.Content = commentsPage;
            flyout.FlyoutWidth = Callisto.Controls.SettingsFlyout.SettingsFlyoutWidth.Wide;
            flyout.HeaderBrush = new SolidColorBrush(ColorHelper.FromArgb(255, 67, 81, 161));
            flyout.Background = new SolidColorBrush(Colors.OrangeRed);
            flyout.HeaderText = "Comments";
            flyout.ContentBackgroundBrush = new SolidColorBrush(Colors.Gray);
            flyout.IsOpen = true;
        }

That’s it, let’s run the app again, display the comments of a post and try posting a comment of our own.

11

12

So, it works. 🙂

This has been a long post, and although I know the article hasn’t been very user friendly and easy to follow I did my best to explain as clearly as possible. Also, we just made a simple demonstration; you can also view the pictures and videos in posts and so on; Facebook has a lot of different post types. The best way to handle it would be preparing different templates (user controls) for different post types and then using ItemTemplateSelector to choose which one to use.

Here‘s the fully working source code of our example.

Thank you for reading, and there may be a part 3 of this article, so stay tuned. 🙂

Advertisement

One thought on “Integrating Facebook in Windows Store Apps Part 2 – Boredom Challenge Day 13

Comment

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 )

Facebook photo

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

Connecting to %s