In a few months Windows 8 will be released. This is an exciting, reimagining of the Windows operating system. With this new operating system comes a new application paradigm. Metro applications are optimized for tablets device. These new applications operate in a restrictive, sandbox environment. This is part of the security that is intended to keep user’s systems safe. Windows developers are used to being able to access all parts of the system when developing their applications. So sharing data between applications is as easy as posting the data to a common location that both applications can access. This could include a local database. This is not possible with Metro applications.
Microsoft has developed a series of contracts that allow your Metro applications become part of the operating system. The Share contract is one of the contracts that allow Metro applications to share content with other Metro applications. Metro applications can’t directly share data with native desktop applications. They can share content through a common cloud/web service infrastructure, passing data back and forth. When Metro applications share data with each other through the share contract they actually work through a broker (the operating system) and there is no direct contact with each other.
The Share Contract
The share contract has three participants, the source application, the target application and the broker. By allowing your application to be a share source and/or a share target, you application becomes part of the Window 8 experience. There is a wealth of data on using the share contract on the MSDN site.
The following are the steps of the Share Activity:
- The user selects the Share charm from the charm bar. The operating system notifies the application in focus of this action through the Data Requested Event.
- If the application in focus has subscribed to this event it becomes the source application. The Source application packages up the data and passes it to the DataPackage to the Broker.
- The Broker inspects the DataPackage’s data format (see the MSDN site for acceptable formats) and displays a list of possible Target apps for the user to select. Target applications have to declare which types they can accept. The user selects a Target application and the Broker passes the DataPackage to the Target.
- Once the Target has handled the DataPackage, it notifies the Broker.
From this interaction you can see the source application has no knowledge of which target application the user will choose nor can it control how the target handles the DataPackage. This keeps the user in control and allows application to be installed without any dependencies.
Custom Data Formats
What happens if you control both the Source and the Target applications? They could be a part of a bigger enterprise system. Can I share data, locally, between the two? One of the acceptable data types for the package is something called Custom Data Format. I interpret this to mean I can pass my business objects between the two applications. So I set out to try this. I started by creating a Source and Target application, and a class library to hold my object model. I added a reference to the class library in the Source and Target applications.
For this sample I created a simple Person object that will be passed to the target application. With contracts you can’t pass the object as they are, they must be serialized. Keep that in mind when designing your objects that get passed.
The Set Up
It took some trial an error to determine how my custom object back and forth. I finally realized that it needed to be serialized so that it can passed between the two applications. Come to find out the DataPackage needs objects to be serialized into an IRandomAccessStream. After figuring this out I decided to create a couple of extension methods to help with this process. Here is the code for the extension methods:
The source application can share from any page in the application. Here is the code from a page in the source set up for sharing:
The first thing you have to do is subscribe to the DataRequested event on the dataTransferManager. You do this in the OnNavigatedTo method of the page. The meat of the code happens in the OnDataRequested method. This callback method gets called when the users selects the share charm. Here the data package is populated. Some key lines to note:
- Line 59: the data package format. This has to match in both the Source and Target. This is how the Broker determine which Target applications to display.
- Line 62: here the Person object is being serialized using the extension method created earlier.
- Line 64: the data package is retrieved from the DataRequestedEventArgs
- Lines 65 and 66: are required properties that need to be set.
- Line 67: the data is set in the DataPackage.
When the user selects the Share charm they are presented with with a share pane. This pane is controlled by the Broker. Here the list of applications that can accept the type of data that we want to pass. This is where the code in Line 59 comes into play. Only applications that have declared that they accept your custom type, will be displayed. If there is more than one application list then the user can select which one they want to handle the data. They are listed in the order of most used application. If you want your application to appear above all others then you need to ensure that users are happy using your applications and use them often. In our case there is only one application that accepts our data type.
The Target Application
Once the user selects your application the data package is passed. Your Target must handle this package. There is a little more work that needs to be done with the Target application. First the Target application must declare that they are a Share Target. This is done in the application manifest. Note that the Data format field must match the data type declared in the source application.
Next the App.xaml.cs file must be modified to handle being activated by the Share Broker. To do that add the following code:
Here an instance of the UI that is displayed is created. The Activate method is called passing the EventArgs which contains the data package.
Now create some UI that is called when you Target is activated via the share charm. Some things to keep in mind are:
- The target application is not being launched fully.
- The UI that is called is hosted by the Broker.
- You only have a limited time before control is passed back to the Source application.
Since your time is limited, limit the amount of time spent handling the data. Usually you will save off the data to be used at a later time.
Here is the simple UI that I created for this demo. The top part of the UI is provided by the Broker.
Next implement the Activate method on your ShareView. Here is my implementation:
Here are the highlights from the Target:
- Lines 48 and 49: get the stream out of the package and serializes it back to the Person object.
- Lines 51 to 56: populates the UI with the values from the object.
- Line 71: notifies the Broker that the Share activity has completed.
In this post I took a look at what it takes to share custom content between two Metro applications. This scenario is great for enterprise applications where a common model can be shared between applications. By implementing the share contract your applications becomes part of the Windows 8 experience. Once user start exploring Windows 8 they will start expect application to part in the different contracts. Take a look at the applications in the Store and see how they handle sharing. This should give you some ideas on what to share from your applications.
You can get the code for the demo application here. Note you must deploy the Target application first or there will be not share target available for the source.
I actually speculate why you labeled this specific blog, “Using the Metro
Share Contract With Custom Data | Dave’s Two Cents”. No matter what I really loved the post!Thanks for the post-Ned
Thanks for taking the time to read it!