{"id":1593,"date":"2009-10-29T14:23:00","date_gmt":"2009-10-29T14:23:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/odatateam\/2009\/10\/29\/using-data-services-over-sharepoint-2010-part-2-crud\/"},"modified":"2009-10-29T14:23:00","modified_gmt":"2009-10-29T14:23:00","slug":"using-data-services-over-sharepoint-2010-part-2-crud","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/odata\/using-data-services-over-sharepoint-2010-part-2-crud\/","title":{"rendered":"Using Data Services over SharePoint 2010 \u2013 Part 2 &#8211; CRUD"},"content":{"rendered":"<p><P>In <A href=\"https:\/\/blogs.msdn.com\/astoriateam\/archive\/2009\/10\/21\/using-data-services-over-sharepoint-2010-part-1-getting-started.aspx\">part 1<\/A> you learned how to get SharePoint 2010 and Astoria working together, how to add a Service Reference to your Client Application and how to do a basic insert. <\/P>\n<P>In this installment you will see full CRUD, so you\u2019ll learn how to do queries, data binding, updates and deletes.<\/P>\n<H3>The Problem:<\/H3>\n<P>In <A href=\"https:\/\/blogs.msdn.com\/astoriateam\/archive\/2009\/10\/21\/using-data-services-over-sharepoint-2010-part-1-getting-started.aspx\">part 1<\/A> we created a \u2018Make a Suggestion\u2019 feature for a department Line of Business application, by storing suggestions in SharePoint 2010.<\/P>\n<P>Now we need a little Silverlight application for reviewing all those suggestions and making comments on them. So we need to display interesting suggestions, to allow the user to provide a comment, or make edits and deletes.<\/P>\n<H3>The Solution:<\/H3>\n<H4>Step 1: Displaying suggestions<\/H4>\n<P>Assuming you\u2019ve set-up your service reference (see <A href=\"https:\/\/blogs.msdn.com\/astoriateam\/archive\/2009\/10\/21\/using-data-services-over-sharepoint-2010-part-1-getting-started.aspx\">part 1<\/A>) the next step is to create XAML to display the Suggestions:<\/P>\n<P><FONT color=\"#0000ff\" face=\"Courier New\">&lt;UserControl x:Class=&#8221;DataServicesOverSharepoint.MainPage&#8221; <BR>&nbsp;&nbsp;&nbsp; xmlns=&#8221;<\/FONT><A href=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\"><FONT color=\"#0000ff\" face=\"Courier New\">http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation<\/FONT><\/A><FONT color=\"#0000ff\" face=\"Courier New\">&#8221; <BR>&nbsp;&nbsp;&nbsp; xmlns:x=&#8221;<\/FONT><A href=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\"><FONT color=\"#0000ff\" face=\"Courier New\">http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml<\/FONT><\/A><FONT color=\"#0000ff\" face=\"Courier New\">&#8221; <BR>&nbsp;&nbsp;&nbsp; xmlns:d=&#8221;<\/FONT><A href=\"http:\/\/schemas.microsoft.com\/expression\/blend\/2008\"><FONT color=\"#0000ff\" face=\"Courier New\">http:\/\/schemas.microsoft.com\/expression\/blend\/2008<\/FONT><\/A><FONT color=\"#0000ff\" face=\"Courier New\">&#8221; xmlns:mc=&#8221;<\/FONT><A href=\"http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006\"><FONT color=\"#0000ff\" face=\"Courier New\">http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006<\/FONT><\/A><FONT color=\"#0000ff\" face=\"Courier New\">&#8221; <BR>&nbsp;&nbsp;&nbsp; mc:Ignorable=&#8221;d&#8221; d:DesignWidth=&#8221;640&#8243; d:DesignHeight=&#8221;480&#8243;&gt; <BR>&nbsp;&nbsp;&nbsp; &lt;Grid x:Name=&#8221;LayoutRoot&#8221; ShowGridLines=&#8221;False&#8221;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid.RowDefinitions&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;5&#8243;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;400&#8243;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;300&#8243;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;30&#8243; \/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;5&#8243; \/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Grid.RowDefinitions&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid.ColumnDefinitions&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ColumnDefinition Width=&#8221;5&#8243;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ColumnDefinition Width=&#8221;500&#8243;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ColumnDefinition Width=&#8221;5&#8243;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Grid.ColumnDefinitions&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ListBox ItemsSource=&#8221;{Binding TrackedSuggestions, Mode=TwoWay}&#8221; Name=&#8221;ListBox&#8221; Grid.Row=&#8221;1&#8243; Grid.Column=&#8221;1&#8243; ScrollViewer.VerticalScrollBarVisibility=&#8221;Auto&#8221;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ListBox.ItemTemplate&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;DataTemplate&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Horizontal&#8221; Margin=&#8221;5&#8243;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Vertical&#8221; Margin=&#8221;5&#8243;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Horizontal&#8221;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Width=&#8221;400&#8243; Text=&#8221;{Binding Title}&#8221; FontWeight=&#8221;Bold&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Horizontal&#8221;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Width=&#8221;400&#8243; Text=&#8221;{Binding Description}&#8221; TextWrapping=&#8221;Wrap&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Button Content=&#8221;Delete&#8221; Click=&#8221;DeleteSuggestion&#8221; Tag=&#8221;{Binding}&#8221; Width=&#8221;50&#8243; Height=&#8221;30&#8243; VerticalAlignment=&#8221;Center&#8221; HorizontalAlignment=&#8221;Center&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/DataTemplate&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/ListBox.ItemTemplate&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/ListBox&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Vertical&#8221; Margin=&#8221;5&#8243; Grid.Column=&#8221;1&#8243; Grid.Row=&#8221;2&#8243;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Horizontal&#8221;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Width=&#8221;100&#8243; Text=&#8221;Title:&#8221; FontWeight=&#8221;Bold&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBox Width=&#8221;300&#8243; Text=&#8221;{Binding ElementName=ListBox, Path=SelectedItem.Title, Mode=TwoWay}&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Horizontal&#8221;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Width=&#8221;100&#8243; Text=&#8221;Description:&#8221; FontWeight=&#8221;Bold&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBox Width=&#8221;300&#8243; Text=&#8221;{Binding ElementName=ListBox, Path=SelectedItem.Description, Mode=TwoWay}&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Horizontal&#8221;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Width=&#8221;100&#8243; Text=&#8221;Created:&#8221; FontWeight=&#8221;Bold&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBox Width=&#8221;300&#8243; Text=&#8221;{Binding ElementName=ListBox, Path=SelectedItem.Created, Mode=TwoWay}&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Horizontal&#8221;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Width=&#8221;100&#8243; Text=&#8221;Modified:&#8221; FontWeight=&#8221;Bold&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBox Width=&#8221;300&#8243; Text=&#8221;{Binding ElementName=ListBox, Path=SelectedItem.Modified, Mode=TwoWay}&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Horizontal&#8221;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Width=&#8221;100&#8243; Text=&#8221;Comments:&#8221; FontWeight=&#8221;Bold&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBox Width=&#8221;300&#8243; Height=&#8221;150&#8243; Text=&#8221;{Binding ElementName=ListBox, Path=SelectedItem.Comments, Mode=TwoWay}&#8221; AcceptsReturn=&#8221;True&#8221; \/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Orientation=&#8221;Horizontal&#8221; Grid.Row=&#8221;3&#8243; Grid.Column=&#8221;1&#8243; Margin=&#8221;5&#8243;&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Button Width=&#8221;100&#8243; Name=&#8221;btnNewSuggestion&#8221; HorizontalAlignment=&#8221;Left&#8221; Content=&#8221;New Suggestion&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Button Width=&#8221;100&#8243; Name=&#8221;btnSaveChanges&#8221; HorizontalAlignment=&#8221;Right&#8221; Content=&#8221;Save Changes&#8221;\/&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/StackPanel&gt; <BR>&nbsp;&nbsp;&nbsp; &lt;\/Grid&gt; <BR>&lt;\/UserControl&gt;<\/FONT> <\/P>\n<P>This XAML code, displays a ListBox (of suggestions) and an series of textboxes for editing the currently selected suggestion. <BR><BR>When running it should looks something like this:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/23\/2019\/02\/SuggestionsVisualizer.jpg\"><IMG title=\"SuggestionsVisualizer\" border=\"0\" alt=\"SuggestionsVisualizer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/23\/2019\/02\/SuggestionsVisualizer_thumb.jpg\" width=\"169\" height=\"244\"><\/A> <\/P>\n<P>To make this work we have a very simple class to encapsulate Data Services and the Data:<\/P>\n<P><FONT face=\"Courier New\">public class SuggestionContext <BR>{ <BR>&nbsp;&nbsp;&nbsp; TeamSiteDataContext _ctx; <BR>&nbsp;&nbsp;&nbsp; DataServiceCollection&lt;SuggestionsItem&gt; _suggestions; <BR>&nbsp;&nbsp;&nbsp; public TeamSiteDataContext DataContext <BR>&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (_ctx == null) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _ctx = new TeamSiteDataContext( <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Uri( <BR>http:\/\/mflasko-dev\/_vti_bin\/listdata.svc, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UriKind.Absolute <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return _ctx; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp; public DataServiceCollection&lt;SuggestionsItem&gt; TrackedSuggestions <BR>&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (_suggestions == null) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _suggestions = DataServiceCollection.CreateTracked&lt;SuggestionsItem&gt;(DataContext); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return _suggestions; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp; } <BR>}<\/FONT><\/P>\n<P>This class has two properties, both evaluated on first access. <\/P>\n<P>One gets the DataServiceContext and the other gets a DataServiceCollection which will hold, and track changes to, a collection of Suggestions. <\/P>\n<P>The SuggestionContext is then exposed as a property of our Silverlight UserControl: <\/P>\n<P><FONT face=\"Courier New\">private SuggestionContext _currentContext; <BR>public SuggestionContext CurrentContext { <BR>&nbsp;&nbsp;&nbsp; get { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (_currentContext == null) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _currentContext = new SuggestionContext(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return _currentContext; <BR>&nbsp;&nbsp;&nbsp; } <BR>}<\/FONT><\/P>\n<P>Next in the constructor of our UserControl we use this as the DataContext for our layout root, we call GetSuggestionsWithNoComments() to retrieve the interesting suggestions, and finally we hookup some event handlers for our buttons, so we can add a new suggestion and save any changes we make back to the database.<\/P>\n<P><FONT face=\"Courier New\">public MainPage() <BR>{ <BR>&nbsp;&nbsp;&nbsp; InitializeComponent(); <BR>&nbsp;&nbsp;&nbsp; GetSuggestionsWithNoComments(); <BR>&nbsp;&nbsp;&nbsp; LayoutRoot.DataContext = CurrentContext; <BR>&nbsp;&nbsp;&nbsp; this.btnSaveChanges.Click += new RoutedEventHandler(SaveChanges_Click); <BR>&nbsp;&nbsp;&nbsp; this.btnNewSuggestion.Click += new RoutedEventHandler(AddNewSuggestion); <BR>}<\/FONT><\/P>\n<P>The GetSuggestionsWithNoComments() method looks like this: <\/P>\n<P><FONT face=\"Courier New\">public void GetSuggestionsWithNoComments() <BR>{ <BR>&nbsp;&nbsp;&nbsp; var query = ( <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from suggestion in CurrentContext.DataContext.Suggestions <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where suggestion.Comments == null <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select suggestion <BR>&nbsp;&nbsp;&nbsp; ) as DataServiceQuery&lt;SuggestionsItem&gt;; <\/FONT><\/P>\n<P><FONT face=\"Courier New\">&nbsp;&nbsp;&nbsp; query.BeginExecute( <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (IAsyncResult asyncResult) =&gt; Dispatcher.BeginInvoke(() =&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataServiceQuery&lt;SuggestionsItem&gt; queryResults = asyncResult.AsyncState as DataServiceQuery&lt;SuggestionsItem&gt;; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (queryResults != null) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurrentContext.TrackedSuggestions.Clear(true); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurrentContext.TrackedSuggestions.Load( <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; queryResults.EndExecute(asyncResult) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , query <BR>&nbsp;&nbsp;&nbsp;&nbsp; ); <BR>}<\/FONT><\/P>\n<P>It executes an asynchronous query to retrieve the interesting suggestions and load them into the CurrentContext.TrackedSuggestions collection. Which in turn causes the ListBox to fill, because of the data binding we\u2019ve set up.<\/P>\n<H4>Step 2: Inserting, Editing and Deleting suggestions<\/H4>\n<P>Now in our XAML we\u2019ve already setup two way data binding from our textboxes back to the suggestion selected in the ListBox, so as we make changes in the TextBoxes the Suggestion is modified, and those changes are tracked by the DataServiceCollection. <\/P>\n<P>So that covers Editing.<\/P>\n<P>Insert is handled by the \u2018New Suggestion\u2019 button. The event handler looks like this:<\/P>\n<P><FONT face=\"Courier New\">void AddNewSuggestion(object sender, RoutedEventArgs e) <BR>{ <BR>&nbsp;&nbsp;&nbsp; CurrentContext.TrackedSuggestions.Add( <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new SuggestionsItem { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Title = &#8220;{Enter a title}&#8221;, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Description = &#8220;&#8221;, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Modified = DateTime.Now, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Created = DateTime.Now <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp; ); <BR>&nbsp;&nbsp;&nbsp; ListBox.SelectedIndex = CurrentContext.TrackedSuggestions.Count &#8211; 1; <BR>}<\/FONT><\/P>\n<P>As you can see this creates a new Suggestion, adds it to the DataServiceCollection, and then tells the ListBox to select the new Suggestion so it can be modified via our TextBoxes.<\/P>\n<P>In our XAML we added a Delete button to each ListBoxItem, this event is bound to those buttons:<\/P>\n<P><FONT face=\"Courier New\">private void DeleteSuggestion(object sender, RoutedEventArgs e) <BR>{ <BR>&nbsp;&nbsp;&nbsp; Button b = sender as Button; <BR>&nbsp;&nbsp;&nbsp; SuggestionsItem toDelete = b.Tag as SuggestionsItem; <BR>&nbsp;&nbsp;&nbsp; CurrentContext.TrackedSuggestions.Remove(toDelete); <BR>}<\/FONT><\/P>\n<P>This relies on the fact that when during DataBinding we put the Suggestion in the button\u2019s Tag property, so all we do when the button is clicked, is retrieve the current Suggestion and remove the suggestion from the TrackedSuggestions collection. This is interpreted as a delete. <\/P>\n<H4>Step 3: Submitting your changes<\/H4>\n<P>Because we are using a DataServiceCollection, every Insert, Edit and Delete is automatically tracked for us. <\/P>\n<P>But as yet they haven\u2019t been committed to the server.<\/P>\n<P>To do that you have to click the \u201cSave Changes\u201d button, which calls this code: <BR><BR><FONT face=\"Courier New\">void SaveChanges_Click(object sender, RoutedEventArgs e) <BR>{ <BR>&nbsp;&nbsp;&nbsp; CurrentContext.DataContext.BeginSaveChanges( <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (IAsyncResult asyncResult) =&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dispatcher.BeginInvoke( <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; () =&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurrentContext.DataContext.EndSaveChanges(asyncResult); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetSuggestionsWithNoComments(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , CurrentContext <BR>&nbsp;&nbsp;&nbsp; ); <BR>}<\/FONT><\/P>\n<P>As per usual the request is invoked asynchronously, in this case by calling BeginSaveChanges. <\/P>\n<P>One thing to note is that once we\u2019ve actually saved the changes we refresh the list of Suggestions by calling GetSuggestionsWithNoComments() again. <\/P>\n<P>The idea here is that once we\u2019ve edited some suggestions they may not longer be interesting for us, or there maybe some new suggestions on the server.<\/P>\n<H3>Summary:<\/H3>\n<P>As you can see it is really easy to create a Silverlight application that uses Data Services to query and manipulate list data.<\/P>\n<P>In Part 3 we will cover how to interact with blobs (i.e. Documents, Images etc), and look&nbsp;out for an upcoming&nbsp;<A href=\"http:\/\/blogs.msdn.com\/astoriateam\/archive\/2009\/11\/05\/enabling-x-domain-access-to-your-data-services.aspx\">blog post covering X-Domain Policy<\/A> which is important if your Silverlight application isn\u2019t hosted on the same web-server as Sharepoint.<\/P>\n<P>As always don\u2019t hesitate to leave a comment.<\/P>\n<P><A href=\"http:\/\/blogs.msdn.com\/alexj\"><STRONG>Alex James<\/STRONG><\/A> <BR>Program Manager Microsoft<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In part 1 you learned how to get SharePoint 2010 and Astoria working together, how to add a Service Reference to your Client Application and how to do a basic insert. In this installment you will see full CRUD, so you\u2019ll learn how to do queries, data binding, updates and deletes. The Problem: In part [&hellip;]<\/p>\n","protected":false},"author":512,"featured_media":3253,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[6,37,66,67,85],"class_list":["post-1593","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-odata","tag-ado-net-data-services","tag-how-to","tag-sharepoint","tag-silverlight","tag-whats-new"],"acf":[],"blog_post_summary":"<p>In part 1 you learned how to get SharePoint 2010 and Astoria working together, how to add a Service Reference to your Client Application and how to do a basic insert. In this installment you will see full CRUD, so you\u2019ll learn how to do queries, data binding, updates and deletes. The Problem: In part [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts\/1593","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/users\/512"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/comments?post=1593"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts\/1593\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/media\/3253"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/media?parent=1593"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/categories?post=1593"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/tags?post=1593"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}