Archives

Archives / 2011 / January
  • .Net Rocks TV - Architecting Windows Phone Applications

    I recently completed a .NET Rocks TV show with Carl Franklin. In this episode I discuss some design decisions that will help you create architecturally sound Windows Phone applications. Of course, many of the techniques will also apply to Silverlight and WPF application development as well. Check out the episode at

    http://www.dnrtv.com/default.aspx?showNum=184

     

    Good Luck with your Coding,
    Paul Sheriff

     

    ** SPECIAL OFFER FOR MY BLOG READERS **
    Visit http://www.pdsa.com/Event/Blog for a free video on Silverlight entitled Silverlight XAML for the Complete Novice - Part 1.

    Read more...

  • Tip on Reusing Classes in Different .NET Project Types

    All of us have class libraries that we developed for use in our projects. When you create a .NET Class Library project with many classes, you can use that DLL in ASP.NET, Windows Forms and WPF applications. However, for Silverlight and Windows Phone, these .NET Class Libraries cannot be used. The reason is Silverlight and Windows Phone both use a scaled down version of .NET and thus do not have access to the full .NET framework class library. However, there are many classes and functionality that will work in the full .NET and in the scaled down versions that Silverlight and Windows Phone use.
    Let’s take an example of a class that you might want to use in all of the above mentioned projects. The code listing shown below might be something that you have in a Windows Form or an ASP.NET application.


    public class StringCommon
    {
      public static bool IsAllLowerCase(string value)
      {
        return new Regex(@"^([^A-Z])+$").IsMatch(value);
      }

      public static bool IsAllUpperCase(string value)
      {
        return new Regex(@"^([^a-z])+$").IsMatch(value);
      }
    }


    The StringCommon class is very simple with just two methods, but you know that the System.Text.RegularExpressions namespace is available in Silverlight and Windows Phone. Thus, you know that you may reuse this class in your Silverlight and Windows Phone projects. Here is the problem: if you create a Silverlight Class Library project and you right-click on that project in Solution Explorer and choose Add | Add Existing Item… from the menu, the class file StringCommon.cs will be copied from the original location and placed into the Silverlight Class Library project. You now have two files with the same code. If you want to change the code you will now need to change it in two places! This is a maintenance nightmare that you have just created. If you then add this to a Windows Phone Class Library project, you now have three places you need to modify the code!

    Add As Link
    Instead of creating three separate copies of the same class file, you want to leave the original class file in its original location and just create a link to that file from the Silverlight and Windows Phone class libraries. Visual Studio will allow you to do this, but you need to do one additional step in the Add Existing Item dialog (see Figure 1). You will still right mouse click on the project and choose Add | Add Existing Item… from the menu. You will still highlight the file you want to add to your project, but DO NOT click on the Add button. Instead click on the drop down portion of the Add button and choose the “Add As Link” menu item. This will now create a link to the file on disk and will not copy the file into your new project.

    Figure 1: Add Existing Item

    Figure 1: Add as Link will create a link, not copy the file over.

    When this linked file is added to your project, there will be a different icon next to that file in the Solution Explorer window. This icon signifies that this is a link to a file in another folder on your hard drive.

    Figure 2: Different icon in Solution Explorer 

    Figure 2: The Linked file will have a different icon to show it is a link.

    Of course, if you have code that will not work in Silverlight or Windows Phone -- because the code has dependencies on features of .NET that are not supported on those platforms – you  can always wrap conditional compilation code around the offending code so it will be removed when compiled in those class libraries.

    Summary
    In this short blog entry you learned how to reuse one of your class libraries from ASP.NET, Windows Forms or WPF applications in your Silverlight or Windows Phone class libraries. You can do this without creating a maintenance nightmare by using the “Add a Link” feature of the Add Existing Item dialog.


    Good Luck with your Coding,
    Paul Sheriff

    ** SPECIAL OFFER FOR MY BLOG READERS **
    Visit http://www.pdsa.com/Event/Blog for a free video on Silverlight entitled Silverlight XAML for the Complete Novice - Part 1.

    Read more...

  • Get XML from Server for Use on Windows Phone

    When working with mobile devices you always need to take into account bandwidth usage and power consumption. If you are constantly connecting to a server to retrieve data for an input screen, then you might think about moving some of that data down to the phone and cache the data on the phone. An example would be a static list of US State Codes that you are asking the user to select from. Since this is data that does not change very often, this is one set of data that would be great to cache on the phone. Since the Windows Phone does not have an embedded database, you can just use an XML string stored in Isolated Storage. Of course, then you need to figure out how to get data down to the phone. You can either ship it with the application, or connect and retrieve the data from your server one time and thereafter cache it and retrieve it from the cache.

    In this blog post you will see how to create a WCF service to retrieve data from a Product table in a database and send that data as XML to the phone and store it in Isolated Storage. You will then read that data from Isolated Storage using LINQ to XML and display it in a ListBox.

    Step 1: Create a Windows Phone Application

    The first step is to create a Windows Phone application called WP_GetXmlFromDataSet (or whatever you want to call it). On the MainPage.xaml add the following XAML within the “ContentPanel” grid:

    <StackPanel>
      <Button Name="btnGetXml"
              Content="Get XML"
              Click="btnGetXml_Click" />
      <Button Name="btnRead"
              Content="Read XML"
              IsEnabled="False"
              Click="btnRead_Click" />
      <ListBox Name="lstData"
                Height="430"
                ItemsSource="{Binding}"
                DisplayMemberPath="ProductName" />
    </StackPanel>

    Now it is time to create the WCF Service Application that you will call to get the XML from a table in a SQL Server database.

    Step 2: Create a WCF Service Application

    Add a new project to your solution called WP_GetXmlFromDataSet.Services. Delete the IService1.* and Service1.* files and the App_Data folder, as you don’t generally need these items. Add a new WCF Service class called ProductService. In the IProductService class modify the void DoWork() method with the following code:

    [OperationContract]
    string GetProductXml();

    Open the code behind in the ProductService.svc and create the GetProductXml() method. This method (shown below) will connect up to a database and retrieve data from a Product table.

    public string GetProductXml()
    {
      string ret = string.Empty;
      string sql = string.Empty;
      SqlDataAdapter da;
      DataSet ds = new DataSet();

      sql = "SELECT ProductId, ProductName,";
      sql += " IntroductionDate, Price";
      sql += " FROM Product";
     
      da = new SqlDataAdapter(sql,
        ConfigurationManager.ConnectionStrings["Sandbox"].ConnectionString);

      da.Fill(ds);

      // Create Attribute based XML
      foreach (DataColumn col in ds.Tables[0].Columns)
      {
        col.ColumnMapping = MappingType.Attribute;
      }

      ds.DataSetName = "Products";
      ds.Tables[0].TableName = "Product";
      ret = ds.GetXml();

      return ret;
    }

    After retrieving the data from the Product table using a DataSet, you will want to set each column’s ColumnMapping property to Attribute. Using attribute based XML will make the data transferred across the wire a little smaller. You then set the DataSetName property to the top-level element name you want to assign to the XML. You then set the TableName property on the DataTable to the name you want each element to be in your XML. The last thing you need to do is to call the GetXml() method on the DataSet object which will return an XML string of the data in your DataSet object. This is the value that you will return from the service call. The XML that is returned from the above call looks like the following:

    <Products>
      <Product ProductId="1"
               ProductName="PDSA .NET Productivity Framework"
               IntroductionDate="9/3/2010"
               Price="5000" />
      <Product ProductId="3"
               ProductName="Haystack Code Generator for .NET"
               IntroductionDate="7/1/2010"
               Price="599.00" />
      ...
      ...
      ...

    </Products>

    The GetProductXml() method uses a connection string from the Web.Config file, so add a <connectionStrings> element to the Web.Config file in your WCF Service application. Modify the settings shown below as needed for your server and database name.

    <connectionStrings>
      <add name="Sandbox"
           connectionString="Server=Localhost;Database=Sandbox;
                             Integrated Security=Yes"/>
    </connectionStrings>

    The Product Table

    You will need a Product table that you can read data from. I used the following structure for my product table. Add any data you want to this table after you create it in your database.

    CREATE TABLE Product
    (
      ProductId int PRIMARY KEY IDENTITY(1,1) NOT NULL,
      ProductName varchar(50) NOT NULL,
      IntroductionDate datetime NULL,
      Price money NULL
    )

    Step 3: Connect to WCF Service from Windows Phone Application

    Back in your Windows Phone application you will now need to add a Service Reference to the WCF Service application you just created. Right-mouse click on the Windows Phone Project and choose Add Service Reference… from the context menu. Click on the Discover button. In the Namespace text box enter “ProductServiceRefrence”, then click the OK button. If you entered everything correctly, Visual Studio will generate some code that allows you to connect to your Product service.

    On the MainPage.xaml designer window double click on the Get XML button to generate the Click event procedure for this button. In the Click event procedure make a call to a GetXmlFromServer() method. This method will also need a “Completed” event procedure to be written since all communication with a WCF Service from Windows Phone must be asynchronous.  Write these two methods as follows:

    private const string KEY_NAME = "ProductData";

    private void GetXmlFromServer()
    {
      ProductServiceClient client = new ProductServiceClient();

      client.GetProductXmlCompleted += new
         EventHandler<GetProductXmlCompletedEventArgs>
          (client_GetProductXmlCompleted);

      client.GetProductXmlAsync();
      client.CloseAsync();
    }

    void client_GetProductXmlCompleted(object sender,
                                       GetProductXmlCompletedEventArgs e)
    {
      // Store XML data in Isolated Storage
      IsolatedStorageSettings.ApplicationSettings[KEY_NAME] = e.Result;

      btnRead.IsEnabled = true;
    }

    As you can see, this is a fairly standard call to a WCF Service. In the Completed event you get the Result from the event argument, which is the XML, and store it into Isolated Storage using the IsolatedStorageSettings.ApplicationSettings class. Notice the constant that I added to specify the name of the key. You will use this constant later to read the data from Isolated Storage.

    Step 4: Create a Product Class

    Even though you stored XML data into Isolated Storage when you read that data out you will want to convert each element in the XML file into an actual Product object. This means that you need to create a Product class in your Windows Phone application. Add a Product class to your project that looks like the code below:

    public class Product
    {
      public string ProductName{ get; set; }
      public int ProductId{ get; set; }
      public DateTime IntroductionDate{ get; set; }
      public decimal Price{ get; set; }
    }

    Step 5: Read Settings from Isolated Storage

    Now that you have the XML data stored in Isolated Storage, it is time to use it. Go back to the MainPage.xaml design view and double click on the Read XML button to generate the Click event procedure. From the Click event procedure call a method named ReadProductXml().Create this method as shown below:

    private void ReadProductXml()
    {
      XElement xElem = null;

      if (IsolatedStorageSettings.ApplicationSettings.Contains(KEY_NAME))
      {
        xElem = XElement.Parse(
         IsolatedStorageSettings.ApplicationSettings[KEY_NAME].ToString());

        // Create a list of Product objects
        var products =
            from prod in xElem.Descendants("Product")
            orderby prod.Attribute("ProductName").Value
            select new Product
            {
              ProductId = Convert.ToInt32(prod.Attribute("ProductId").Value),
              ProductName = prod.Attribute("ProductName").Value,
              IntroductionDate =
                Convert.ToDateTime(prod.Attribute("IntroductionDate").Value),
              Price = Convert.ToDecimal(prod.Attribute("Price").Value)
            };

        lstData.DataContext = products;
      }
    }

    The ReadProductXml() method checks to make sure that the key name that you saved your XML as exists in Isolated Storage prior to trying to open it. If the key name exists, then you retrieve the value as a string. Use the XElement’s Parse method to convert the XML string to a XElement object.

    LINQ to XML is used to iterate over each element in the XElement object and create a new Product object from each attribute in your XML file. The LINQ to XML code also orders the XML data by the ProductName. After the LINQ to XML code runs you end up with an IEnumerable collection of Product objects in the variable named “products”. You assign this collection of product data to the DataContext of the ListBox you created in XAML. The DisplayMemberPath property of the ListBox is set to “ProductName” so it will now display the product name for each row in your products collection.

    Summary

    In this article you learned how to retrieve an XML string from a table in a database, return that string across a WCF Service and store it into Isolated Storage on your Windows Phone. You then used LINQ to XML to create a collection of Product objects from the data stored and display that data in a Windows Phone list box. This same technique can be used in Silverlight or WPF applications too.

    NOTE: You can download the complete sample code at my website. http://www.pdsa.com/downloads. Choose Tips & Tricks, then "Get XML From Server for Use on Windows Phone" from the drop-down.

    Good Luck with your Coding,
    Paul Sheriff

    ** SPECIAL OFFER FOR MY BLOG READERS **
    Visit http://www.pdsa.com/Event/Blog for a free video on Silverlight entitled Silverlight XAML for the Complete Novice - Part 1.

     

    Read more...

  • Get Application Title from Windows Phone

    In a Windows Phone application that is currently in development, I needed to be able to retrieve the main Application Title of the phone application. You can set the value for Deployment Title in the properties sheet of your Windows Phone Application, however getting to this value programmatically can be a little tricky.

    This article assumes that you have Visual Studio 2010 and the Windows Phone tools installed along with it. The Windows Phone tools must be downloaded separately and installed after Visual Studio 2010. You may also download the free Visual Studio 2010 Express for Windows Phone developer environment.

    The WMAppManifest.xml File

    First off, you need to understand that when you set the Deployment Title in the Properties sheet of your Windows Phone application, this title is stored in an XML file located under the \Properties folder of your application. This XML file is named WMAppManifest.xml. A portion of this file is shown in the following listing.

    <?xml version="1.0" encoding="utf-8"?>
    <Deployment
      xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment"
      AppPlatformVersion="7.0">
      <App xmlns=""
           ProductID="{71d20842-9acc-4f2f-b0e0-8ef79842ea53}"
           Title="Mobile Time Track"
           RuntimeType="Silverlight"
           Version="1.0.0.0"
           Genre="apps.normal"
           Author="PDSA, Inc."
           Description="Mobile Time Track"
           Publisher="PDSA, Inc.">
     ...
     ...
      </App>
    </Deployment>

    Notice the “Title” attribute in the <App> element in the above XML document. This is the value that gets set when you modify the Deployment Title in the Properties window of your Phone project. The only value you can set from the Properties window is the Title. All of the other attributes you see here must be set by going into the XML file and modifying them directly.

    Note that this information duplicates some of the information that you can also set from the Assembly Information… button in the Properties window. We can only speculate why Microsoft did not just use that information instead of creating another file to maintain.

    Reading Attributes from WMAppManifest

    Next, I searched through all the namespaces and classes within the Windows Phone DLLs and could not find a way to read the attributes within the <App> element using a Windows Phone class. Thus, I had to resort to good old fashioned XML processing. So, I created a WinPhoneCommon class and added two static read-only properties as shown in the snippet below:

    public class WinPhoneCommon
    {
      /// <summary>
      /// Get the Application Title
      /// from the WMAppManifest.xml file
      /// </summary>
      public static string GetApplicationTitle
      {
        get { return GetWinPhoneAttribute("Title"); }
      }

      /// <summary>
      /// Get the Application Description
      /// from the WMAppManifest.xml file
      /// </summary>
      public static string GetApplicationDescription
      {
        get { return GetWinPhoneAttribute("Description"); }
      }

      ... GetWinPhoneAttribute method here ...
    }

    In your Windows Phone application you can now simply call WinPhoneCommon.GetApplicationTitle or WinPhone.GetApplicationDescription to retrieve the Title or Description properties from the WMAppManifest.xml file respectively. You notice that each of these properties makes a call to the GetWinPhoneAttribute method. This method is shown in the following code snippet:

    /// <summary>
    /// Gets an attribute from the Windows Phone WMAppManifest.xml file
    /// To use this method, add a reference to the System.Xml.Linq DLL
    /// </summary>
    /// <param name="attributeName">The attribute to read</param>
    /// <returns>The Attribute's Value</returns>
    private static string GetWinPhoneAttribute(string attributeName)
    {
      string ret = string.Empty;

      try
      {
        XElement xe = XElement.Load("WMAppManifest.xml");
        var attr = (from manifest in xe.Descendants("App")
                    select manifest).SingleOrDefault();
        if (attr != null)
          ret = attr.Attribute(attributeName).Value;
      }
      catch
      {
        // Ignore errors in case this method is called
        // from design time in VS.NET
      }

      return ret;
    }

    I love using the new LINQ to XML classes contained in the System.Xml.Linq.dll. When I did a Bing search the only samples I found for reading attribute information from WMAppManifest.xml used either an XmlReader or XmlReaderSettings objects. These are fine and work, but involve a little extra code. Instead of using these, I added a reference to the System.Xml.Linq.dll, then added two using statements to the top of the WinPhoneCommon class:

    using System.Linq;
    using System.Xml.Linq;

    Now, with just a few lines of LINQ to XML code you can read to the App element and extract the appropriate attribute that you pass into the GetWinPhoneAttribute method.

    Notice that I added a little bit of exception handling code in this method. I ignore the exception in case you call this method in the Loaded event of a user control. In design-time you cannot access the WMAppManifest file and thus an exception would be thrown.

    Summary

    In this article you learned how to retrieve the attributes from the WMAppManifest.xml file. I use this technique to grab information that I would otherwise have to hard-code in my application. Getting the Title or Description for your Windows Phone application is easy with just a little bit of LINQ to XML code.

    NOTE: You can download the complete sample code at my website. http://www.pdsa.com/downloads. Choose Tips & Tricks, then "Get Application Title from Windows Phone" from the drop-down.

    Good Luck with your Coding,
    Paul Sheriff

    ** SPECIAL OFFER FOR MY BLOG READERS **
    Visit http://www.pdsa.com/Event/Blog for a free video on Silverlight entitled Silverlight XAML for the Complete Novice - Part 1.

    Read more...