Exercise 1: Creating a Silverlight Application Using the Client Object Model
Task 1 – Create a Silverlight Application Using the Client Object Model
In this task, you will create a Silverlight application which uses the Client Object Model to query list items.
- Launch Visual Studio 2010 and open the lab project by clicking File >> Open >> Project\Solution...
- Browse to C:\%Office365TrainingKit%\Labs\4.1\Source\Before\TimeEntrySearch.sln and open the solution.
- Note: If prompted to install the Silverlight Developer Runtime, click OK and complete the install.
- In the Solution Explorer, click on the TimeEntrySearchSL project to expand the project.
- Expand the References node.
- Microsoft.SharePoint.Client.Silverlight and Microsoft.SharePoint.Client.Silverlight.Runtime are the Client Object Model binaries for Silverlight. They are referenced from C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE \LAYOUTS\ClientBin\.
- In the TimeEntrySearchSL project, open MainPage.xaml.
Replace the XAML markup in MainPage.xaml with the following markup.
(Toolbox code snippet 4.1.1)
<UserControl x:Class="TimeEntrySearchSL.MainPage" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:sdk="https://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" xmlns:my="clr-namespace:TimeEntrySearchSL" mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600"> <Grid x:Name="LayoutRoot" Background="White" > <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBox Name="txtSearchTask" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Margin="5"/> <Button Name="TimeEntrySearchButton" Content="Search" Grid.Column="2" Grid.Row="0" Margin="5" HorizontalAlignment="Stretch" Click="TimeEntrySearchButton_Click" /> <data:DataGrid Name="TimeEntryDataGrid" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3" Margin="5" AutoGenerateColumns="False" ItemsSource="{Binding TimeEntries, Mode=OneWay}" > <data:DataGrid.Columns> <data:DataGridTextColumn CanUserReorder="True" Header="ID" CanUserResize="True" CanUserSort="True" Width="*" Binding="{Binding Id}" /> <data:DataGridTextColumn CanUserReorder="True" Header="Date" CanUserResize="True" CanUserSort="True" Width="*" Binding="{Binding BillableDate}" /> <data:DataGridTextColumn CanUserReorder="True" Header="Task" CanUserResize="True" CanUserSort="True" Width="2*" Binding="{Binding Task}" /> <data:DataGridTextColumn CanUserReorder="True" Header="Employee" CanUserResize="True" CanUserSort="True" Width="2*" Binding="{Binding Employee}" /> <data:DataGridTextColumn CanUserReorder="True" Header="Hours" CanUserResize="True" CanUserSort="True" Width="*" Binding="{Binding Hours}" /> </data:DataGrid.Columns> </data:DataGrid> </Grid> </UserControl>
- Save MainPage.xaml.
- In the Solution Explorer, select the TimeEntrySearchSL project and right-click MainPage.xaml and select View Code.
- Note the using directive for the Microsoft.SharePoint.Client namespace; this allows you to access the SharePoint Client Object Model from your Silverlight code.
- Also note the _clientContext module level variable; you will use this to make all calls to SharePoint that use the Client Object Model.
Find the GetBillableTimeEntries method.
This method will setup the ClientContext, create a CamlQuery, define the asynchronous callback, and execute the query.
- Add the following code to the GetBillableTimeEntries method (TODO 4.1.2):
_clientContext = ClientContext.Current; _timeEntries.Clear(); List timeEntries = _clientContext.Web.Lists.GetByTitle("Billable Time"); CamlQuery camlQueryTimeEntryList = new CamlQuery(); camlQueryTimeEntryList.ViewXml = @"<View> <Query> <Where> <BeginsWith> <FieldRef Name='Task' /> <Value Type='Text'>" + txtSearchTask.Text + @"</Value> </BeginsWith> </Where> </Query> </View>"; _timeEntryListItems = timeEntries.GetItems(camlQueryTimeEntryList); _clientContext.Load(_timeEntryListItems); _clientContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed);
Add the callback methods onQuerySucceeded and onQueryFailed to MainPage.xaml.cs (TODO 4.1.3).
private void onQuerySucceeded(object sender, ClientRequestSucceededEventArgs args) { Deployment.Current.Dispatcher.BeginInvoke(DisplayEntries); } private void onQueryFailed(object sender, ClientRequestFailedEventArgs args) { Deployment.Current.Dispatcher.BeginInvoke( () => MessageBox.Show("Execution Failed:" + args.Exception.InnerException.Message)); }
These methods use the Dispatcher to invoke a method on the UI thread.
Add the following code to the DisplayEntries method (TODO 4.1.4):
foreach (ListItem time in _timeEntryListItems) { TimeEntry t = new TimeEntry(); t.Id = int.Parse(time["ID"].ToString()); t.Employee = time["Employee"].ToString(); t.Task = time["Task"].ToString(); t.BillableDate = DateTime.Parse(time["BillableDate"].ToString()); t.Hours = Single.Parse(time["Hours"].ToString()); _timeEntries.Add(t); } TimeEntryDataGrid.ItemsSource = null; TimeEntryDataGrid.ItemsSource = _timeEntries;
This method is invoked by the UI thread and will loop the list items returned by the query and create a collection of TimeEntry objects. The list will be used as a data source for the TimeEntryDataGrid control defined in XAML.
- Right-click the TimeEntrySearchSL project node in the Solution Explorer and select Build.