VSTO Data Islands allows finer architecture of "Information Worker" applications

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

By using of office documents, it is often required to prepare some data for document before the user opens it.

This scenario is typical for web application. User goes online and downloads the document. However, immediately before downloading the server should append some data to document, so the user can change it.

After the user has changed the data the document is uploaded on the server.

This is very common scenario. To solve this problem it was required to install the office application on the server. The web application then would start the application by COM automation etc.

Such architecture was never a way I recommended. Unfortunately, this was often the only way.

 

The VSTO offers a new feature called “Data Islands”. It is really not a revolutionary feature, but it could have a huge impact on the architecture of “Information Worker” applications.

 

VSTO data islands provide two key features:

 

-         Persisting (embedding) of the data in the document.

-         Manipulating of embedded (persisted) data without of creating of the instance of the certain office application.

 

Following example show how to use data islands. The example consists of two small projects. The first one is the VSTO (office) project based on WinWord and second one is the console application simulating some external process, which manipulates the data embedded in the document.

First, the data has to be defined, which will be cached (embedded-persisted) in document. For this purpose only serializable data can be used.

Then define corresponding fields (not properties) as public and declare the attribute [Cached()].

In this example the string ‘Name’ and dataset ‘Ds’ are used.

When the document is started first time both fields have to be set on some value. This ensures that serialized values are stored in the cache.

 

 

using System;
using
System.Data;
using
System.Drawing;
using
System.Windows.Forms;
using
Microsoft.VisualStudio.Tools.Applications.Runtime;
using
Word = Microsoft.Office.Interop.Word;
using
Office = Microsoft.Office.Core;

namespace WordDocument5
{
    public partial class ThisDocument
    {
       [Cached()]
       public string Name;

        [Cached()]
        public DataSet Ds;

        private void ThisDocument_Startup(object sender, System.EventArgs e)
        {
            if (Ds == null)
                Ds = new DataSet();

            if (String.IsNullOrEmpty(Name))
                Name = "-";

        }

      . . .

    }

}

 

Now let’s take a look on the second projects. The example bellow shows how some application (independent on office) can manipulate cached data. It shows how to write the data in the cache and how to read it.

The method Write() reads the content of the XML file, which is serialized RFID tag, and persists it in the VSTO cache.

Please note that all cached variables are stored in the collection HostItems. In this example hard-coded value WordDocument5.ThisDocument is used to retrieve the host (property containing cached values).

In general cached values can be retrieved by using of following generic syntax:
 

      doc.CachedData.HostItems(<ViewName>).CachedData(<DataName>)

 

where:

<ViewName> The name of the „View“, which contains the data. If Winword is used the view name is consisted as “DocumentName.ThisDocument”. Document name is the name of the winword document and ThisDocument is the name of the class implementing VSTO functionality. If Excel is used then each sheet represents one view.

<DataName> The name of the cached variable, which is preserved by attribute Cached(). See first example.

 
using
System;
using
System.Data;
using
Microsoft.VisualStudio.Tools.Applications.Runtime;

namespace ConsoleApplication1
{
    class Program
   
{
        private static string m_Xml = @"abc.tag.xml";

        // TODO: Change this path.
       
private static string filename = @"D:\MyProjects\DaenetProjects\DiverseTests\VSTO\WordDocument5\WordDocument5\bin\Debug\WordDocument5.doc";

         static void Main(string[] args)
        {
            if (ServerDocument.IsCustomized(filename))
            {
                Write();

                Read();
            }
        }

        /// <summary>
       
/// Writes the data to document cache.
       
/// </summary>
       
static void Write()
        {
            if (ServerDocument.IsCacheEnabled(filename))
            {
                using (ServerDocument doc = new ServerDocument(filename))
                {
                    CachedDataHostItem host = doc.CachedData.HostItems["WordDocument5.ThisDocument"];                   

                    host = doc.CachedData.HostItems["WordDocument5.ThisDocument"];

                    CachedDataItem dsItem = host.CachedData["Ds"];                   

                    System.Data.DataSet Ds = new DataSet();
                   
Ds.ReadXml(m_Xml);
 
                    dsItem.SerializeDataInstance(Ds);

                    CachedDataItem nameItem = host.CachedData["Name"];               

                    nameItem.SerializeDataInstance("Damir2");
 

                    doc.Save();

                }
            }
        }

 

        /// <summary>
     
  /// Reads the data from document cache.
       
/// </summary>
       
static void Read()
        {
            if (ServerDocument.IsCacheEnabled(filename))
            {
                using (ServerDocument doc = new ServerDocument(filename))
                {
                    CachedDataHostItem host = doc.CachedData.HostItems["WordDocument5.ThisDocument"];

                    host = doc.CachedData.HostItems["WordDocument5.ThisDocument"];

                    CachedDataItem dsItem = host.CachedData["Ds"];

                    System.IO.StringReader xmlReader = new System.IO.StringReader(dsItem.Xml);

                    System.IO.StringReader schemaReader = new System.IO.StringReader(dsItem.Schema);

                    System.Data.DataSet Ds = new DataSet();

                    Ds.ReadXmlSchema(schemaReader);

                    Ds.ReadXml(xmlReader);
                }
           
}
        }
    }
}

 

 Some more information about this feature you can find here and here.

Damir Dobric


Posted Apr 13 2006, 05:53 PM by Damir Dobric
Filed under:

Comments

Rolf Nebhuth wrote re: VSTO Data Islands allows finer architecture of &quot;Information Worker&quot; applications
on 04-19-2006 15:55
I have some strange behavior with VSTO

I Have definied some variables with the cache attribute in a word application . But in the Server Application I have not filled all of them with data. If I Opened the word document no of the varialbe are filled.

The Solution is you must fill all cached variables!!!
Damir Dobric wrote re: VSTO Data Islands allows finer architecture of &amp;quot;Information Worker&amp;quot; applications
on 04-19-2006 16:33
Unfortunately you are right Rolf. I have noticed the same behavior.
The example in my post contains the workaround because of this “strange feature” 
As you can see I also do initialization of cached variables (which are unfortunately not properties – one more “strange feature”) too.
The code bellow shows how to avoid this behavior.

 private void ThisDocument_Startup(object sender, System.EventArgs e)
       {
           if (Ds == null)
               Ds = new DataSet();
         
if (String.IsNullOrEmpty(Name))
               Name = "-";
       }

damir dobric
developers.de is a .Net Community Blog powered by daenet GmbH.