Saturday, November 24, 2012

Windows 8 + Salesforce.com Part 3

In my last two posts I showed how to connect to Salesforce.com from a Windows 8 Windows Store application, and then how to retrieve a list of accounts. In this article I will show how to display the accounts.
The first thing we need is a view model class to hold the data we want to display. For an application this simple we could get away without a view model but creating one is a good practice and it does make things easier for more complex applications.

public class AccountsViewModel : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;

    private ObservableCollection<sfdcAccount> accounts;

    public ObservableCollection<sfdcAccount> Accounts
    {
        get { return accounts; }
        set {
            accounts = value;
                if (PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs("Accounts"));
        }
    }
  
}

You will notice that that class implements the INotifyPropertyChanged interface. This is needed so that XAML data binding can detect changes to the object. The implementation of the interface is in the first line, the PropertyChanged event which needs to be called whenever a property of the object changes. The rest of the class is a property that holds an ObservableCollection of sfdcAccounts. In the setter you will see that we raise the PropertyChanged event passing in a reference to the object and a PropertyChangedEventArgs object containing the name of the property. Even though this is an ObservableCollection it only allows the data binding to see when items are added to or removed from the collection. The PropertyChanged event is needed to notify data binding if the actual collection object referenced by the property changes.

Next we need a new page to display the accounts, so from the project select Add/New Item, then select Items Page and change the name to AccountsView.xaml. You will get a message asking to add files to your project, select Yes. To have this page displayed at startup open App.xaml.cs and in the OnLaunched function change MainPage in the following line to AccountsView.

if (!rootFrame.Navigate(typeof(MainPage), args.Arguments))

While we are in App.xaml.cs we need to create an sfdcLibrary object that we can use throughout our application. To do this add the following property

public static sfdcLibrary SFDC { get; set; } 

then add the following line to the App() constructor

SFDC = new sfdcLibrary();

Now lets work on the AccountsView we created earlier. In AccountsView.xaml.cs you will notice that the class inherits from LayoutAwarePage. This is a helper class that is part of the Windows Store Application template which wraps the base Page class and provides help with things like navigation.  The first change we need to make in this file is to add this private variable which will hold the view model

private AccountsViewModel model = new AccountsViewModel();

Next replace the LoadState function with this one

protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
    this.DataContext = model;
    if (await App.SFDC.LoginSalesforce())
    {
        var acc = await App.SFDC.ReadAccounts();
        model.Accounts = acc.records;
    }
}

LoadState is called in response to the OnNavigatedTo event which happens whenever a page is displayed.  The first thing we do in this function is set the page’s DataContext property to the view model. DataContext will be used as the base for all the data binding we do on the page. Next we call the LoginSalesforce function to do the OAuth login and if it is successful we read the account list from Salesforce and assign it to the Accounts property of the viewmodel.

We are almost done, the final changes we need to make are in AccountsView.xaml. First in the Page.Resources section change the source to point to the Accounts property of the view model like this

Source="{Binding Accounts}"/>

This will bind the Accounts list in our view model to the GridView which will display the data. Next thing we need is a DataTemplate to be used to display each account.

<DataTemplate x:Key="StandardItemTemplate">
    <StackPanel Orientation="Vertical" Width="200" Height="200" Background="#FF07B3F3"  >
        <TextBlock  Text="{Binding Name}" HorizontalAlignment="Center" Margin="20,10,20,0" FontWeight="Bold" TextWrapping="Wrap" FontSize="20" TextAlignment="Center" />
        <TextBlock Text="{Binding AccountNumber}" HorizontalAlignment="Center" Margin="20,10"/>
    </StackPanel>
</DataTemplate>

The template starts with a 200x200 StackPanel with a blue background. Inside this we have two TextBlocks, the first one will show the Name of the account and the second will show the AccountNumber. Finally we need to change the ItemTemplate property of the GridView to use the template we just defined.

ItemTemplate="{StaticResource StandardItemTemplate}"

StaticResource tells XAML that we are using a resource defined elsewhere in the markup, in this case in our Page.Resources section. StandardItemTemplate is the Key property we defined in the template markup.

If we run the application we will first get a Salesforce login screen. Once the correct username and password are entered all the accounts in the Salesforce instance will be displayed.

image

Now that we have a basic working application I will expand on it in future blog posts.
You can download the full source for this application here. To use this code you will need to put your ClientID and ClientSecret in the sfdcLibrary class.

No comments: