Displaying Microsoft Dynamics CRM records in Listview using Xamarin

In the previous Blog Post we connected Dynamic CRM with Xamarin Form application using ADAL authentication and CRM mobile helper library and executed the WhoAmIRequest.

In this blog post, we’ll continue with the previous project and retrieve Account records from Dynamic CRM, display them in list view (List-View is used for displaying lists of data) and show details of records in detail page when user taps a record.

1. Add Accounts Class

Add Accounts Class to your Portable Project. In this class we will declare the variables for account data as shown below.


using Microsoft.Xrm.Sdk.Samples;

using System;

namespace XamarinWithCRM

{

public class Accounts

{

public string name { get; set; }

public string owner { get; set; }

public decimal revenue { get; set; }

public int noOfEmployees { get; set; }

public string email { get; set; }

public Boolean donotAllowEmail { get; set; }

public DateTime createdOn { get; set; }

public OptionSetValue businessType { get; set; }

public string businessTypeText { get; set; }

}

}

2. Adding a Main page
Add a Xaml page to your Portable project. Right Click your portable project, click Add |Add New Item. Select “Forms Xaml Page”. Name it “MainPage” and click Add as shown below.mainPage

 

Make this page the root page of your application by adding the line shown below to the constructor of App.cs and comment other code in the constructor of App.cs.


MainPage = new NavigationPage(new MainPage());

3. Adding xaml Code

Add the following code to MainPage.xaml. We shall use ListView. ListView is a view for presenting lists of data, especially long lists that require scrolling.


<?xml version="1.0" encoding="utf-8" ?>

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"

xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

x:Class="XamarinWithCRM.MainPage">

<Grid>

<Grid.RowDefinitions>

<RowDefinition Height="Auto"></RowDefinition>

<RowDefinition Height="Auto"></RowDefinition>

</Grid.RowDefinitions>

<Button x:Name="myButton" Text="Sign in to CRM" Grid.Row="1"></Button>

<ListView x:Name="AccountsList" Grid.Row="2">

<ListView.ItemTemplate>

<DataTemplate>

<ViewCell>

<StackLayout >

<Label Text="{Binding name}" FontSize="Large"/>

</StackLayout>

</ViewCell>

</DataTemplate>

</ListView.ItemTemplate>

</ListView>

</Grid>

</ContentPage>

 

4. Retrieve Accounts From CRM

Add the RetrieveAccounts function to MainPage.xaml.cs file. In this function we shall use OrganizationDataWebServiceProxy (defined in Add Microsoft.Crm.Sdk.Mobile sample) to retrieve data from CRM. We shall also use QueryExpression for our query and EntityCollection the result of our query. These terms are defined in Microsoft.Crm.Sdk.Mobile sample.

If you want the ListView to automatically update as items are added, you’ll need to use an ObservableCollection. ObservableCollection is defined in System.Collections.ObjectModel and is just like List, except that it can notify ListView of any changes.

Create instance of ObservableCollection as shown below.


private ObservableCollection<Accounts> accountList = new ObservableCollection<Accounts>();

Add the following line to the constructor. ListView is populated with data using the ItemsSource property, which can accept any collection implementing IEnumerable.

AccountsList.ItemsSource = accountList;

The definition of RetrieveAccounts is as shown below.


public async Task RetrieveAccounts()

{

accountList.Clear();

try

{

QueryExpression qe = new QueryExpression("account");

qe.ColumnSet.AddColumns("name", "revenue", "numberofemployees", "emailaddress1",

"donotpostalmail", "createdon", "ownerid",

"businesstypecode");

EntityCollection accountsRecord = await proxy.RetrieveMultiple(qe);

foreach (Entity accountRecord in accountsRecord.Entities)

{

Accounts accountClass = new Accounts();

if (accountRecord.Contains("name") && accountRecord.Attributes["name"] != null)

accountClass.name = accountRecord["name"].ToString();

if (accountRecord.Contains("revenue") && accountRecord.Attributes["revenue"] != null)

accountClass.revenue = (Money)accountRecord["revenue"];

if (accountRecord.Contains("numberofemployees") && accountRecord.Attributes["numberofemployees"] != null)

accountClass.noOfEmployees = (int)accountRecord["numberofemployees"];

if (accountRecord.Contains("emailaddress1") && accountRecord.Attributes["emailaddress1"] != null)

accountClass.email = accountRecord["emailaddress1"].ToString();

if (accountRecord.Contains("donotpostalmail") && accountRecord.Attributes["donotpostalmail"] != null)

accountClass.donotAllowEmail = (bool)accountRecord["donotpostalmail"];

if (accountRecord.Contains("createdon") && accountRecord.Attributes["createdon"] != null)

accountClass.createdOn = (DateTime)accountRecord["createdon"];

if (accountRecord.Contains("ownerid") && accountRecord.Attributes["ownerid"] != null)

accountClass.owner = (EntityReference)accountRecord["ownerid"];

if (accountRecord.Contains("businesstypecode") && accountRecord.Attributes["businesstypecode"] != null){

accountClass.businessType = (OptionSetValue)accountRecord["businesstypecode"];

accountClass.businessTypeText = accountRecord.FormattedValues["businesstypecode"].ToString();

}

accountList.Add(accountClass);

}

}

catch (Exception ex)

{

await DisplayAlert("Error", "This: " + ex, "got it");

}

}

And call this function from the MyButton_Clicked method and also make instance and initialize the proxy “OrganizationDataWebServiceProxy”.


private OrganizationDataWebServiceProxy proxy= new OrganizationDataWebServiceProxy();

proxy.ServiceUrl = Constants.ServiceURL;

proxy.AccessToken = authResult.AccessToken;

await RetrieveAccounts();

Execute the application, the list of Accounts will be shown as shown in below screenshot.

listRecord

5. Adding detail Page

Add a xaml page and name it “DetailedPage”. In this page we will show the details of the tapped record.

1.addDetailpage

Add the following code to the constructor of the “DetailedPage” page.


public DetailedPage(Accounts accounts)

{

InitializeComponent();

var layout = new StackLayout { Padding = new Thickness(5, 10) };

this.Content = layout;

var nameLabel = new Xamarin.Forms.Label { FontSize = 28};

nameLabel.Text = accounts.name;

nameLabel.TextColor = Color.Blue;

nameLabel.HorizontalTextAlignment = TextAlignment.Center;

layout.Children.Add(nameLabel);

Grid grid = new Grid

{

VerticalOptions = LayoutOptions.FillAndExpand,

RowDefinitions =

{

new RowDefinition { Height = GridLength.Auto },

new RowDefinition { Height = GridLength.Auto },

new RowDefinition { Height = GridLength.Auto },

new RowDefinition { Height = GridLength.Auto },

new RowDefinition { Height = GridLength.Auto },

new RowDefinition { Height = GridLength.Auto },

new RowDefinition { Height = GridLength.Auto },

new RowDefinition { Height = GridLength.Auto }

},

ColumnDefinitions =

{

new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },

new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }

}

};

grid.Children.Add(new Xamarin.Forms.Label

{

Text = "Email",

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label)),

},0,0);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = accounts.email,

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label)),

}, 1, 0);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = "Revenue",

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label)),

}, 0, 1);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = accounts.revenue.ToString(),

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label)),

}, 1, 1);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = "Business Type",

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label)),

}, 0, 2);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = accounts.businessTypeText,

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label)),

}, 1, 2);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = "Created On",

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label)),

}, 0, 3);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = accounts.createdOn.ToString(),

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label)),

}, 1, 3);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = "Do not Allow Email",

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label))

}, 0, 4);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = accounts.donotAllowEmail.ToString(),

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label))

}, 1, 4);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = "No of Employees",

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label))

}, 0, 5);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = accounts.noOfEmployees.ToString(),

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label))

}, 1, 5);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = "Owner",

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label))

}, 0, 6);

grid.Children.Add(new Xamarin.Forms.Label

{

Text = accounts.owner,

FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Xamarin.Forms.Label))

}, 1, 6);

layout.Children.Add(grid);

}

6. Navigation from list record to detail page.

Implement ListView.ItemTapped method in the constructor of the MainPage.xaml.cs. This method will navigate to the detail page when user taps a record.

Add the following event to MainPage.xaml.cs.


AccountsList.ItemTapped += AccountsList_ItemTapped;

async private void AccountsList_ItemTapped(object sender, ItemTappedEventArgs e)

{

Accounts accounts = (Accounts)e.Item;

if (e.Item != null)

{

await Navigation.PushAsync(new DetailedPage(accounts));

}

}

Run the application and result will be shown when a record has been tapped as shown in screenshot below.

detailPage

 

 



1 Comment

Leave a Reply