Tips/Tricks: Where is DataGrid in Microsoft Expression Blend 2.5?

This post is just a tip for those who are not able to find DataGrid in Expression Blend 2.5 (March 2008 Preview). Laurent Duveau asked this question in Silverlight forum. I tried to find this solution and replied him in this post.

No datagrid in Blend 2.5? Yes, Silverlight Datagrid doesn’t show by default in the toolbox of Blend. The controls that you see on that toolbox are from System.Windows.Controls namespace. Silverlight Datagrid is NOT under that namespace. So, Datagrd is under which namespace? That control is under System.Windows.Controls.Data namespace. Okay. How to add Datagrid control to toolbox? Yes. This is the reason why I wrote this post. Please keep on reading further. I will tell you the step-by-step as below.

1. Expand the “Reference” node in Expression Blend to check whether System.Windows.Controls.Data.dll is already referenced in the project or not.

Blend Reference

2. If that dll is not there then right-click on the “References” node and select “Add Reference”

Add References

3. Go to the Silverlight SDK folder (e.g. C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Libraries\Client) . Select “System.Windows.Controls.Data.dll” to add as a reference in your Blend project.

data-dll-added.jpg

4. Click on “Asset Library” as shown in picture below

Click Asset Library

5. Click “Show All” and Select “Datagrid” in Asset Library

datagrid-in-asset-library.jpg

6. Finally, you got the Datagrid control on toolbox as you want.

datagrid-on-toolbox.jpg

Yes.. Good Job! you have successfully added the Datagrid control to Blend. :)

ADO.NET Data Service (Astoria) in Silverlight 2 (beta1)

Download : SL2Astoria.zip (1.21 MB)

vs-design-view.jpg

Content

  • Introduction
  • Background
  • Creating database in SQL 2005
  • Creating Silverlight project and ADO.NET Data Service in Visual Studio 2008
  • Creating a XMLHttpRequestWrapper class
  • Inserting new record in Silverlight
  • Updating the existing record in Silverlight
  • Retrieving the record from Database in Silverlight
  • Deleting the record in Silverlight
  • FAQs

Introduction

This post is written for those who like to use Astoria in Silverlight 2 before Astoria Team release the new version of Astoria Silverlight add-on. This post will guide you how to insert new record to database, how to update, retrieve or delete the existing records from the database using ADo.NET Data Service (Astoria) in Silverlight 2. You all know that Astoria Client addon for SL 2 (beta1) is not compatible with SL2beta1 and the next verion of Astoria Client addon won’t be available until end of April so that I can’t use that addon in this post either. but I will use XmlHttpRequest wrapper instead of Astoria client add-on for consuming Astoria from Silverlight. (Thanks to Jackbone from Silverlight forum for contributing very light-weight XmlHttpRequest wrapper code.).

As this post is focusing on how to do CRUD operations with Astoria in SL, I’m not gonna include other markups or animation in this post. I hope it would be easier for you to read the code that you really need.

Background

As I wrote a few articles about how to use Astoria in Silverlight 1.1 Alpha here and here, desopedr (one of my reader of my blog) and a few friends asked me how to use Astoria in Silverlight 2 (beta1).

  • The first attempt was simple. I tried to use Astoria add-on in Silverlight project but it didn’t work. When I read the Astoria forum, I found that the current version of Astoria addon doesn’t work with SL2b1. (You can read about that here and here.)
  • Secondly, I tried to use Web Client to do CRUD operations with Astoria in SL. I could successfully retrieve the data from Astoria service by using WebClient but we can’t make httpPost request or etc with WebClient so that the operations (e.g. insert) that requires other http verbs (e.g. POST, PUT, DELET) can’t be done with WebClient. So, the second attempt was failed too.
  • Then, I tried using HttpWebRequest to invoke Astoria service from Silverlight. but whenever I tried to invoke, I always get “null” for response. I’m not sure whether this is Silverlight issue or not. I posted this issue in forum and you can read this issue here.
  • After the third attempt was failed, I got the idea to invoke the service using XmlHttpRequest object from Javascript. then, Jackbond posted the Silverlight XmlHttpRequest Wrapper in our forum. (You can read the original post here.) So, I decided to use his wrapper instead of pure Javascript. After spending some times, I can successfully CUD operations with that wrapper. (I have a few problems in updating so that I’m not able to include about this for now. but I will update once I got the solution.) In this article, I will share you how to do CUD operations with Astoria in Silvrlight 2 beta1.

Creating database in SQL 2005

You have to create one table called Products with the following structure below. I have written so many time how to create a database and table in SQL 2008 so I ain’t gonna repeat here again. Please read “Creating the database in SQL 2005″ section of this post if you don’t know how to create the table.

table.jpg

Creating Silverlight project and Astoria Service in Visual Studio 2008

1. Create new project with the name “SL2Astoria” in VS 2008.

new-project-thumb.jpg

2. Attach ASP.NET project with Silverlight.

add-silverlight.jpg

ADO.NET Entity Data Model

1. Right-click on ASP.NET project and Select “Add New Item”.

2. Choose “ADO.NET Entity Data Model” and Click “OK” button

edm.jpg

3. The following dialog will be shown (It’s asking where you want to put EDM.) Click “Yes” button

app_code.jpg

4. Choose “General” and Click “Next” button

emd-wizard.jpg

5. Select the connectionstring if you already have. If there is nothing shown in connection, please click “New Connection” to create new connection. After that, click “Next” button

choose-your-data-connect.jpg

6. Unchecked all objecs first and select the table that you want. (In my case, I checked the table named “Products” only and unchecked all other tables, views and stored procedures.)

choose-your-database-object.jpg

7. Click “Finish” button.

ADO.NET Data Service

1. Right-click on ASP.NET project and Add “ADO.NET Data Service”

adonet-data-service.jpg
2. Change the sourcecode as below in WebDataService.cs. First thing we need to do is that we have to set our data model class in WebDataService. In my case, MyStoreModel.MyStoreEntities is the data model class. Then, enable the operations from our data service . Note that it’s just for testing purpose. You should not enable all operations in production.

public class WebDataService : WebDataService<MyStoreModel.MyStoreEntities>
{
// This method is called once during service initialization to allow
// service-specific policies to be set
public static void InitializeService(IWebDataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are
// visible, updatable, etc.
// (for testing purposes use "*" to indicate all entity sets/service
// operations, but that option should NOT be used in production systems)

// Example for entity sets (this example uses "AllRead" which allows reads but not writes)
config.SetResourceContainerAccessRule("*", ResourceContainerRights.All);

// Example for service operations
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);

}

// Query interceptors, change interceptors and service operations go here
}

That’s all we need to do in ASP.NET project.

Creating a XMLHttpRequestWrapper class

XMLHttpRequestWrapper class is just a wrapper class of Javascript XmlHttpRequest object. If you are familiar with Ajax, I’m sure that you have good understanding about this object. In my example, this wrapper class is just like the way that we wrote in Javascript except I used C# instead of Javascript.


using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
using System.Text;
using System.Xml;
namespace SL2Astoria {
/// <summary>
/// Ref: http://silverlight.net/forums/t/11508.aspx
/// </summary>
public static class XMLHttpRequestWrapper {
static ScriptObject _xmlHttpRequest;

public static void DoPost(Uri url, string httpVerb) {
DoPost(url, httpVerb, string.Empty);
}
public static void DoPost(Uri url, string httpVerb, string param) {
_xmlHttpRequest = HtmlPage.Window.CreateInstance("XMLHttpRequest");

_xmlHttpRequest.Invoke("open", httpVerb, url, false);
_xmlHttpRequest.Invoke("setRequestHeader", "Content-Type", "application/json");

if (param == string.Empty) {
_xmlHttpRequest.Invoke("send");
}
else {
_xmlHttpRequest.Invoke("send", param);
}
}
}
}

CRUD operations with Astoria in Silverlight

After creating this wrapper class, we can start writing the code for CRUD operations with Astoria. but before that, you should understand which http verbs we will use for each operation. Please take a look at the table below.

Operations HTTP verbs
Insert POST
Retrieve GET
Delete DELETE
Update PUT

Inserting new record in Silverlight

We will start with inserting new record to database. In order to insert new record, we have to make Http POST request to Astoria Data Service. We will pass the data as a JSON object to that service. Yes. I hard-coded the service URL in my code. It’s just a sample, right? I’m not showing the best practice of using Silverlight. I’m just showing how to use XmlHttpRequestWrapper class to deal with Astoria. ProductName from json object is the property of entity set of Astoria and it’s also the column name of “Products” table.

string productName = "ComponentOne Silverlight Studio";
string serviceURL = "http://localhost:52976/SL2Astoria_Web/WebDataService.svc/Products/";

string jsonString = "{" + Environment.NewLine;
jsonString += "ProductName:\"" + productName + "\"" + Environment.NewLine;
jsonString += "}" + Environment.NewLine;

XMLHttpRequestWrapper.DoPost(new Uri(serviceURL), "POST", jsonString);

Updating the existing record in Silverlight

[As I told you earlier, I'm having some problems in updating. I will update this post once I got the solution. Please keep on watching.]

Retrieving the record from Database in Silverlight

Currently, there are two way to retrieve the data from Astoria in Silverlight. You can use either WebClient or XmlHttpRequestWrapper class.

string serviceURL = "http://localhost:52976/SL2Astoria_Web/WebDataService.svc/Products?$orderby=ProductID";

string result = XMLHttpRequestWrapper.DoPost(new Uri(serviceURL), "GET");

The following code is the same as the code above. But It uses WebClient instead of XmlHttpRequestWrapper.

void retrieveButton_Click(object sender, RoutedEventArgs e) {
try {

string serviceURL = "http://localhost:52976/SL2Astoria_Web/WebDataService.svc/Products?$orderby=ProductID";

////retriving data
WebClient astoriaService = new WebClient();
astoriaService.DownloadStringCompleted += new DownloadStringCompletedEventHandler(AstoriaService_DownloadStoriesCompleted);
astoriaService.DownloadStringAsync(new Uri(serviceURL));
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}

void AstoriaService_DownloadStoriesCompleted(object sender, DownloadStringCompletedEventArgs e) {
if (e.Error == null) {
DisplayProducts(e.Result);
}
}

Deleting the record in Silverlight

The following code is for deleting the existing data from database. All we need to do is that we specify the id of project in service URL and send the HTTP DELETE request to Astoria to delete that record.


string serviceURL = "http://localhost:52976/SL2Astoria_Web/WebDataService.svc/Products(18)/";
XMLHttpRequestWrapper.DoPost(new Uri(serviceURL), "DELETE");

FAQs

1. I have downloaded the sample. How can I run this sample?

There is MyStore.mdf in SQL Database folder. You should attach this database to MS SQL in your machine. Then, you need to change the connection string in ASP.NET project.

2. Why did you hard-code the service URL?

Yes. I hard-coded the service URL in my code. It’s just a sample, right? I’m not showing the best practice of using Silverlight. I’m just showing how to use XmlHttpRequestWrapper class to deal with Astoria.

3. Why don’t you make nice-looking UIs in your sample? Are you just lazy?

No. I have been trying to do this since last week. As I told you in “Background” section of this article, I have tried a lot of ways and I faced a lot of problems during these days. Until now, I still have some problems in updating. but I know that there are some people (e.g. desopedr ) is waiting to know how to do CRUD operations with Astoria in Silverlight. So, I just make this sample and I wrote this article in very short and limited time. I hope I will be able to create another sample with nice-looking UIs in future.

Another thing is that I just want to focus on the functionality. If I put a lot of controls, animation and etc, there will be a lot of codes for reader to look at. So, I made this sample with the code that are required only.

4. Does it support cross-domain?

No. This wrapper has exactly the same limitations as what XmlHttpRequest object has. Another thing is that invoking the Astoria data service is not in async-mode. However, you can change it easily if you want.

That’s all. I hope you might find it useful. Feel free to let me know if you have any problem or comment. Thanks.