Accessing and Managing Word 2007 Content Control with VSTO

In the last post, I have talked about how Content Control brings you more consistent data validation. In this post, let’s continue on the document we’ve worked on. Please refer here should you want to follow the rest of this article. Moreover, I provide a solution that contain (ASP.NET Website and database) in order to preview the data that we are going to insert later.

Please download the solution here.

If you have successfully downloaded and opened up the solution, you will see something like the left picture. Simple double click on Default.aspx and select view in browser, the you will see as the right picture. The page illustrates number of products that have already inserted to the database. Now our goal is to build a Word file and save it to the database.

image image

Let’s do the VSTO now.

1. Add a VSTO Project to the solution. To do that, click on File – Add – New Project.

image image

Select your preferable language (I’ll choose C#, want to know why?), Choose Office – 2007 on the project types (left pane). On the templates (right pane), select Word 2007 Document. Fill the title as VSTOWordDoc. Click Ok.

2. The will be a pop up dialog prompting for the document that we’re going to working on. You can choose to build your new document or select existing. In this case, just use the document that we’ve discussed before on this post. In case you have download the document, grab it here.

image

Choose Copy an existing document and click the browse button. Select your document and click OK.

3. You will now see there’s word document inside your Visual Studio. Wow…Eye-rolling

image

Let’s do some work there. Remember, our goal on this post is how to save the filled document to the database. First step is to give the name on these Content Controls. Therefore, we can access them easily. Simple click each of the content control and change as below.

Product Name Name : productName
LockContentControl : True
Order Date Name : orderDate
LockContentControl: True
Bill To Name : billTo
LockContentControl: True
Unit Name : unit
LockContentControl: True
Picture Name : picture
LockContentControl: True

4. Prepare the web service. We’ll need to prepare the web service as bridge between our VSTO Document with the database. Since in this case, the database residing to the server that only the web app can access it. To create the web service, follow the steps below.

Right click on the web project, choose Add New Item, choose Web Service, fill ProductService as the Name.

image

 

5. If you notice Bill To field, it’s actually a list of department in your company. Since they are probably will store as a look up table in your database. We can add them programmatically. We’ll make use of the web service we create before to return the number of department list.

On the ProductService.cs, add the following code below the HelloWorld() method.

   1: [WebMethod]
   2: public string[] GetDepartments()
   3: {
   4:     string[] deptList = { "IT", "Finance", "HR", "Accounting", "Purchasing" };
   5:     return deptList;
   6: }

In this sample, I didn’t access database to get the department list since I haven’t prepare the database. But on that level, we’re all sure that it is very possible to do that. To simplify, I just return a number of string.

6. Next, we’re going to prepare a method to add a new product. Add the following code below the GetDepartments() method.

   1: [WebMethod]
   2: public void AddProduct(Product pro)
   3: {
   4:     using (DatabaseEntities ent = new DatabaseEntities())
   5:     {
   6:         ent.AddToProduct(pro);
   7:         ent.SaveChanges();
   8:     }
   9: }

Remember to add the namespace on the top of code –> using DatabaseModel; (Since Product and DatabaseEntities class is in DatabaseModel namespace that’s automatically generated by ADO.NET Entity Framework)

7. Consume the web service from VSTO Project. When we’ve successfully prepare the web service, it’s time to consume it from our VSTO project. Right click on our VSTO project, choose Add Service Reference. Click Discover (because it’s in one solution, you can type the public address if your web service are hosted somewhere on the cloud). Fill ProductServiceReference as namespace.

You will see the generated proxy from Visual Studio as following if you’ve successfully consuming the web service.

image

8. Referring to No 5, now we’re going to populate the list of Department List on the BillTo drop down list.

Make sure we have removed the existing lists before. Select the BillTo drop down list, click on DropDownListEntries –> Collection, click on […] button.

Remove all entries.

image

Right click on ThisDocument.cs and choose View Code.

There’re two method that are automatically generated:

  • ThisDocument_StartUp that would automatically called when the document is starting up
  • ThisDocument_ShutDown that would automatically called when the document is shutting down.

Add the following code to replace the default ThisDocument_StartUp

   1: private void ThisDocument_Startup(object sender, System.EventArgs e)
   2: {
   3:     ProductServiceReference.ProductServiceSoapClient client = new VSTOWordDoc.ProductServiceReference.ProductServiceSoapClient();
   4:     int idx = 0;
   5:     foreach (var dep in client.GetDepartments())
   6:     {
   7:         billTo.DropDownListEntries.Add(dep, dep, idx);
   8:         idx++;
   9:     }
  10: }

Run the VSTO App to test your drop down list to ensure that it’s successfully added at the runtime.

Set the start up project to our VSTO Word Project and Run F5.

You’ll see something like this is if you successfully received the data from web service.

image

9. Next we are going to access the value on the content control and save it to the database via the web service.In order to do that we need to add “something” such as button to trigger the action. Therefore, let’s add a custom ribbon by right click on the VSTO project, Add – Add New Item. Select Office on the left pane (Categories) and Ribbon (Visual Designer) on the right pane (Visual Studio Installed templates). Just leave the ribbon name by default.

image

Drag two buttons to the group1 inside of the TabAddIns Ribbon.

  • One for “Check Connection”. This is just only to test whether it’s connected to the web service. If it’s not, we can save it to the local offline and try again when it’s connected Open-mouthed. (I rename the name of the control to “btnCheckConnection”).
  • And another one for “Send it to server” is to save the values to the database. (I rename the name of the control to btnSubmit).

10. Double click the CheckConnection button and simple add the following code.

   1: private void btnCheckConnection_Click(object sender, RibbonControlEventArgs e)
   2: {
   3:     ProductServiceSoapClient client = new ProductServiceSoapClient();
   4:     if (client.HelloWorld().Equals("Hello World"))
   5:         MessageBox.Show("Successfully connected");
   6:     else
   7:         MessageBox.Show("Not connected, please try again later");
   8: }

Remember to add namespace System.Windows.Form because MessageBox class requires it. And also the web service reference VSTOWordDoc.ProductServiceReference.

11. Back to the “Ribbon1” design view and double click on the button “Send it to server”. Add the following code there.

   1: public byte[] ImageToByteArray(System.Drawing.Image imageIn)
   2: {
   3:     MemoryStream ms = new MemoryStream();
   4:     imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
   5:     return ms.ToArray();
   6: }
   7:  
   8: public bool IsValid()
   9: {
  10:     int unit = 0;
  11:     return int.TryParse(Globals.ThisDocument.unit.Text, out unit);             
  12: }
  13:  
  14: private void btnSubmit_Click(object sender, RibbonControlEventArgs e)
  15: {
  16:     if (IsValid())
  17:     {
  18:         Product pro = new Product();
  19:         pro.ProductName = Globals.ThisDocument.productName.Text;
  20:         pro.OrderDate = Convert.ToDateTime(Globals.ThisDocument.orderDate.Text);
  21:         pro.Unit = Convert.ToByte(Globals.ThisDocument.unit.Text);
  22:         pro.Picture = ImageToByteArray(Globals.ThisDocument.picture.Image);
  23:         pro.BillTo = Globals.ThisDocument.billTo.Text;
  24:  
  25:         ProductServiceSoapClient client = new ProductServiceSoapClient();
  26:         client.AddProduct(pro);
  27:         MessageBox.Show("Product has been successfully added");
  28:     }
  29:     else
  30:         MessageBox.Show("Please fill in unit with integer");
  31: }

The method ImageToByArray is to return the array of byte from parameter image since we are going to save the picture to the database.

Before saving the product to database, we need also to ensure that the data to be stored are all valid as required. That’s the reason why I prepare the IsValid() method.

Remember to add the namespace System.IO because MemoryStream class requires it.

12. Now let’s run the application by pressing F5 and see what happen.

Let’s try to insert the invalid data.

As expected, it fails Smile.

image

 

 

 

 

 

 

Now, let’s insert some proper data.

image

Let examine the ASP.NET page to see whether the product is really inserted or not.

image

Aha! Successfully inserted.

Now you see, we can integrate the Office successfully with VSTO.

I hope you enjoy this long post Open-mouthed.

See you!

Wely

Microsoft MVP, Visual C#

Share this post: | | | |
Published Friday, June 19, 2009 9:39 PM by Wely
Filed under: ,

Comments

# re: Accessing and Managing Word 2007 Content Control with VSTO

Wednesday, June 24, 2009 3:21 PM by Wiwiek Abbas

Kerennnnn...thanks yah Wel, untung aja ada blog loe ini, soalnya kemarin gw nggak sempet nyatet sampai selengkap ini...

Powered by Community Server (Commercial Edition), by Telligent Systems