How to display an End User License Agreement (EULA) in Windows Phone 7

28Jul11

Introduction

In this blog, I will demonstrate a way of displaying an End User License Agreement (EULA) in a Windows Phone 7 (WP7) application (app). Why is a blog like this one necessary? To be honest, showing an EULA is not as easy as it seems. Here are some problems that I have encountered.

1. You usually want the EULA to be the first thing a user sees after they launch your app. One may think, “That’s easy, put it in a page.” The problem is that you do not really want to put an EULA into a page. Placing an EULA into its own page will mean that that page will be placed on the page backstack. This option can lead to a whole host of problems. For example, imagine you have a page, MainPage.xaml, and in that page, you detect if a user has accepted the EULA, if not, then you navigate to EulaPage.xaml. Once the user is on the EulaPage, if they accept the EULA, you can navigate back to MainPage, but what happens if the user declines the EULA? You can navigate back to MainPage too, but what you really want is to quit the application. That means you have to pass some parameter back to MainPage from EulaPage, which is very possible (pass using a querystring value or global value in App). But then in the MainPage, you have to detect, (most likely by overriding Page.OnNavigatedTo) if there’s any parameters passed in and handle it appropriately. This option may quickly create a mess out of your coding logic as you may have to handle multiple unrelated concerns when MainPage is navigated to. Another good discussion of not using a separate XAML page to display an EULA is available here at Exiting a Windows Phone Application.

2. An EULA is very long. In WP7, you cannot display very long texts in a TextBlock control. Even if you place a TextBlock inside a ScrollViewer, you will not be able to show a very long text because no UIElement can be longer than 2048 pixels (in width or height). (Unless, of course, your EULA is very short). The advised method, or a method, of displaying a very long text is to break it up and store the broken components inside multiple controls (e.g. TextBlocks).

Method

The approach I will be demonstrating to show an EULA uses a Popup. In this way, we avoid putting the EULA on its own XAML page. Also, the technique used to display a very long text such as an EULA is to break the text up into chunks. A ListBox is then bounded to the text chunks, and each ListItem inside the ListBox is bounded to a single text chunk by way of a TextBlock. Lastly, when and if a user decides to decline the EULA, the application quits. Now, you really can’t programmatically quit a WP7 app; so the technique used to quit an app is to throw an exception; this technique is borrowed from this blog post, How to Quit a WP7 Silverlight Application.

Showing the EULA Popup

First, I create an EULA control, EulaControl.xaml. The main thing to note here is there is a ListBox. Inside the ListBox, I define the ListBox.ItemTemplate, and it has a TextBlock. Again, the ListBox will be bounded to a List of Objects having a property/field Text.

        <ListBox x:Name="lbEula" Grid.Row="0" Grid.Column="0"
                 SelectionChanged="lbEula_SelectionChanged"
                 ScrollViewer.VerticalScrollBarVisibility="Auto"
                 Margin="0,0,0,0">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Text}"
                               TextWrapping="Wrap"
                               IsHitTestVisible="False"
                               Width="470"
                               />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

When the application launches, the first page that is shown is MainPage.xaml. Inside the constructor, I check if the user has already accepted the EULA, if not, then I show the popup. The code to check if a user has accepted the EULA is shown below.

            bool userAcceptedEula = false;
            var store = IsolatedStorageSettings.ApplicationSettings;
            if (store.Contains(EULA_KEY))
                userAcceptedEula = (bool)store[EULA_KEY];

            if (!userAcceptedEula)
            {
                InitEulaPopup();
            }

The code to actually show the Popup is shown below.

            EulaControl eula = new EulaControl();
            //... code omitted

            _eulaPopup = new Popup();
            _eulaPopup.Child = eula;
            _eulaPopup.IsOpen = true;

Breaking up the very long EULA text

Now, let’s talk about breaking up the very long EULA text. Inside the EulaControl’s code-behind, I load the EULA as follows. Notice that Eula.txt is a text file placed in a folder, Asset, and its build action action is set to Content. After I load the EULA text, I instantiate a LongText object; LongText object actually breaks up the EULA text. I then bind the ListBox, lbEula, to the List, of LongText.

            Uri uri = new Uri("Assets/Eula.txt", UriKind.Relative);
            var resource = App.GetResourceStream(uri);
            String str = "";

            using (System.IO.StreamReader reader = new System.IO.StreamReader(resource.Stream))
            {
                str = reader.ReadToEnd();
            }

            LongText longText = new LongText(str);
            lbEula.ItemsSource = longText.Texts;

TextItem is just a plain old C# object (POCO). It looks like the following.

    public class TextItem
    {
        public string Text { get; set; }

        public TextItem(string text)
        {
            Text = text;
        }
    }

LongText breaks the EULA into a List of TextItem. It has a method, public List ToList(string str), that breaks the EULA apart. It looks like the following. There are multiple ways to break up the text. In this approach, I tried to make sure that text that should not be broken up stay in one TextBlock, while at the same time kept the number of TextItems very low. You do not want a lot of TextItems created for performance reasons; a lot of TextItems mean a lot of TextBlocks, which can be very slow to load/display.

        public List<TextItem> ToList(string str)
        {
            List<TextItem> texts = new List<TextItem>();

            int length = str.Length;
            string[] tokens = str.Split(new string[] { "\r\n" }, StringSplitOptions.None);
            StringBuilder sb = new StringBuilder();
            foreach (string token in tokens)
            {
                sb.Append(token);

                if (sb.Length >= MAX)
                {
                    string text = sb.ToString();
                    texts.Add(new TextItem(text));
                    sb.Length = 0;
                }
                else
                {
                    sb.Append("\r\n");
                }
            }

            if (sb.Length > 0)
            {
                string text = sb.ToString();
                texts.Add(new TextItem(text));
            }

            return texts;
        }

Handling a user’s response

As I stated previously, EulaControl displays the Eula, but it also handles the user’s response (i.e. whether she accepts or declines the EULA). Inside EulaControl.xaml.cs, I define the following delegate and event.

        public delegate void UserRespondedEventHandler(bool accepted);
        public event UserRespondedEventHandler UserResponded;

There are 2 buttons that the user may click representing Accept and Decline. The event handlers for these buttons are shown below.

        private void btnAccept_Click(object sender, RoutedEventArgs e)
        {
            if (null != UserResponded)
                UserResponded(true);
        }
        private void btnDecline_Click(object sender, RoutedEventArgs e)
        {
            if (null != UserResponded)
                UserResponded(false);
        }

Quitting the app

In MainPage.xaml.cs, I have defined an anonymous handler. If the user signals that she does not want to accept the EULA, we call App.Quit(), which is a static method that throws an exception.

            eula.UserResponded += (bool accepted) =>
            {
                if (null != _eulaPopup)
                    _eulaPopup.IsOpen = false;
                if (!accepted)
                {
                    App.Quit();
                }
                else
                {
                    //save or persist the fact that a user has accepted the EULA
                    //... code omitted
                }
            };

The App.Quit() method looks like the following.

        public static void Quit()
        {
            //my debugger still catches this as an unhandled exception
            //the world doesn't come crashing down, however
            throw new Wp7EulaPopup.Exception.QuitException();
        }

The App.Application_UnhandledExceptio(…) method looks like the following.

        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            //if the exception is of type QuitException, do nothing
            //taken from http://www.imaginativeuniversal.com/blog/post/2010/08/22/How-to-Quit-a-WP7-Silverlight-Application.aspx.
            if (e.ExceptionObject is Wp7EulaPopup.Exception.QuitException)
                return;

            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                System.Diagnostics.Debugger.Break();
            }
        }

Summary and Conclusion

In this blog I discussed an approach to showing a very long EULA text using a Popup, and how to handle a user’s reponse by storing the value and/or quitting the application. In hindsight, as is always the case for me, this approach did not seem to terribly difficult to arrive at, but getting there was not intuitive or met with resistance due to the limitations/constraints of WP7. The full source code is licensed under the Apache 2.0 license and may be downloaded by clicking this link http://www.box.net/shared/83c70qehpov7fsuxtup7. Enjoy and cheers! Sib ntsib dua nawb mog.

About these ads


No Responses Yet to “How to display an End User License Agreement (EULA) in Windows Phone 7”

  1. Leave a Comment

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: