Thursday, May 17, 2012    
Blog  

OpenLight Blog

Getting the right behaviors in your Phone 7 App – Part 3 Email ‘em

Dec 22

Written by:
12/22/2010 8:45 AM  RssIcon

This example will cover how to package a EmailComposeTask as a reusable behavior that can be dropped into any given Phone 7 app. The EmailComposeTask has a few properties that are used to pass data to the email you are launching / preparing to send.

These include the following:

  • Body
  • Cc
  • Subject
  • To

Due to the fact that there are four properties included with this task, as opposed to the one property we dealt with in Part 1 and Part 2, we will not be able to use the Tag property of the associated control in the same way as in those examples. With that said, we will in fact use the Tag property but we will have to do a little extra magic to get it to work. Thankfully that Tag property is of type object which gives us the flexibility we will need to make this work. In order to make this solution as reusable as possible I decided to use an interface that can be used in any project referencing this code. Before I loose you, give me one more moment of your time to see how simple this really is. Here is the interface:

public interface IEmailComposeData
{
        string Body { get; set; }
        string Cc { get; set; }
        string Subject { get; set; }    
        string To { get; set; }
}

Whoa, ok so it just mimics the properties exposed by the EmailComposeTask! Why in the world would I do something like this?!? We the answer is actually pretty simple, to leverage the powerful binding framework baked into Silverlight. An example is probably the easiest way to explain this, so here is a class that I used in a recent project.

    public partial class Submission
        : IEmailComposeData
    {
        public Submission()
        {
        }
        #region IEmailComposeData Members
        public string Body
        {
            get { return string.Empty; }
            set { }  //No op
        }
        public string Cc
        {
            get { return string.Empty; }
            set { }  //No op
        }
        public string Subject
        {
            get { return "Thank you for your feedback of " + this.ApplicationName; }
            set { }  //No op
        }
        public string To
        {
            get { return this.EmailAddress; }          
            set { }  //No op
        }
        #endregion
    }

What I did here is I created a partial class of a class generated by a service reference and wrapped a few properties into the IEmailComposeData interface. I also included a little prefix text to the subject and a property from the generated class. The point this should illustrate is that you can implement this interface in any class and provide the expected properties to the behavior, which I will show here:

public class LaunchEmailComposeAction : TriggerAction<Control>
{
    public bool UseDataObject { get; set; }
    protected override void Invoke(object o)
    {
        EmailComposeTask task = new EmailComposeTask();
        if (this.UseDataObject)
        {
            var data = this.AssociatedObject.Tag as IEmailComposeData;
            task.Body = data.Body;
            task.Cc = data.Cc;                
            task.Subject = data.Subject;
            task.To = data.To;
        }
        else
        {
            task.To = this.AssociatedObject.Tag.ToString();
        }
        task.Show();
    }
}

 

As you can see, the behavior includes a property UseDataObject to tell the Invoke method if it should try to cast the AssociatedObject’s Tag to the provided interface and pull the data out of it for the properties of EmailComposeTask. If the UseDataObject is set to false then it tries to grab a To string out of the Tag property. I included this just for simple situation when you simply want to launch an email with the To field filled out automatically. However, using the data object allows you to create XAML that looks like this:

<HyperlinkButton
	 Content="{Binding EmailAddress, Mode=OneWay}"
	 Tag="{Binding Mode=OneWay}">
	<Custom:Interaction.Triggers>
		<Custom:EventTrigger EventName="Click">
			<ITLackey_Phone7_Common_Behaviors:LaunchEmailComposeAction  UseDataObject="True" />
		</Custom:EventTrigger>
	</Custom:Interaction.Triggers>
</HyperlinkButton>

In this XAML the EmailAddress from the Submission class (shown above) is used as the content and the Submission object itself is bound to the Tag property. Since we implemented the IEmailComposeData interface in the Submission class it will be successfully parsed by the behavior and the email will be prepopulated with the information provided by the properties of the Submission class. In this case the To field will be filled in with the EmailAddress and the Subject will be filled in with “Thank you for your feedback of “ + ApplicationName.

I completely understand and acknowledge that this example includes additional complexity compared to the examples shown in Part 1 & 2; however, I hope that the power of repackaging this task for reusability can be seen and will out weigh the little bit of extra complexity. Obviously, you can trim this down to support only a single field or however you see fit. This solution worked for me and allowed me to pass in all of the data the task supports and is open to add data if the task is expanded to include some additional properties such as ATTACHMENT (hint hint Windows Phone 7 Team! Winking smile ).

 

Hope this helps!

Tags:
Categories:

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Add Comment   Cancel 
  
Copyright 2009 by OpenLightGroup.net   |  Privacy Statement  |  Terms Of Use