latest posts

If you simply want to download the library, click here or download the sample + library, click here. Like many folks who have been doing Windows Phone development for a while now, they might have been upset as I was to find DataSets were not part of the supported runtime. For those that don't know there is a powerful tool that has come with Visual Studio for quite some time now called xsd. xsd is a command line tool that can take an XML file and create a typed dataset class for you to include in your C# applications. I have used this feature extensively for a large offline Windows Forms application I originally wrote in the Spring of 2009 and am still using it today to read and write to XML files. To use the xsd tool I typically launch the Visual Studio Developer Console as shown below or you execute it directly from C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools (If I remember correctly it was under Visual Studio\SDK\bin prior to VS2012). [caption id="attachment_1658" align="aligncenter" width="264"] Visual Studio 2012 Developer Command Prompt[/caption] The premise of using the xsd tool is to take an XML file like so: [xml] <?xml version="1.0" standalone="yes"?> <CPUSockets> <CPUSocket> <Name>Socket F</Name> <NumberOfPins>1307</NumberOfPins> <IsLGA>True</IsLGA> </CPUSocket> <CPUSocket> <Name>Socket A</Name> <NumberOfPins>462</NumberOfPins> <IsLGA>False</IsLGA> </CPUSocket> </CPUSockets> [/xml] Do the following command line: [powershell] xsd cpusockets.xml /d [/powershell] This will generate an xsd file. From there you can open this xsd file in Visual Studio to set the column variable types, nullable values etc. and then run the command below or simply run it and it will generate all string column types in your typed dataset class: [powershell] xsd cpusockets.xsd /d [/powershell] The benefit of using Typed Data Sets when working with XML files is that you don't have any hard coded values, everything is extremely clean. For instance to read in the XML shown above all it requires is: [csharp] CPUSockets cpuSockets = new CPUSockets(); cpuSockets.ReadXml("cpusockets.xml"); [/csharp] Very clean and at that point you can iterate over the rows like you would any DataSet (i.e. with TPL, a Foreach loop, LINQ etc). One advantage I found in using straight xml files with the xsd tool is that a non-programmer can assist with the creation of the XML files' schema and can be updated with just Notepad later on. Being the sole programmer at an 80+ employee company leads me to make things very easy to maintain. Bringing me back to my dilemma (and a most likely a lot of other Windows Phone 7.x/8 developers). Server side I have been able to generate XML and read it in my WCF services using the above method, but I wanted a universal code base between Windows Phone and WCF or as close to it as possible. Previously I had written an abstract class with some abstract functions with 2 implementations. One via simply using XmlReader for Windows Phone and the other via Typed Data Sets. Definitely not an ideal situation. Thinking about this problem yesterday I came up with a clean solution and I am sharing it with any one who wishes to use it and figuring I am going to be having a lot of these epiphanies, I am simply bundling the classes into a library called, jcWPLIBRARY, keeping with my other project naming conventions. So how does this solution work? First off I am going to assume you have a class you're already using or something similar to keep the structure of your XML file. With my solution you're going to need to inherit the jcWPLIBRARY.XML.XMLReaderItem class with your own properties like so: [csharp] public class CPUSockets : jcWPLIBRARY.XML.XMLReaderItem { public string Name { get; set; } public int NumberOfPins { get; set; } public bool IsLGA { get; set; } } [/csharp] How does reading and writing from XML files look? I created a small sample to show the steps. It is a pretty simple Windows Phone 8 application with one button to write XML with some hard coded test data and the other button to read that file back in from IsolatedStorage. [caption id="attachment_1660" align="alignleft" width="180"] Sample jcWPLIBRARY XML application[/caption] [caption id="attachment_1662" align="aligncenter" width="180"] Sample jcWPLIBRARY XML application[/caption] Going along with every thing I have done in the last year or two, I've tried to make it universal and easy to use. The source code behind the Write XML button: [csharp] List<Objects.CPUSockets> cpuSockets = new List<Objects.CPUSockets>(); cpuSockets.Add(new Objects.CPUSockets { IsLGA = true, Name = "Socket F", NumberOfPins = 1207 }); cpuSockets.Add(new Objects.CPUSockets { IsLGA = false, Name = "Socket AM3+", NumberOfPins = 942 }); cpuSockets.Add(new Objects.CPUSockets { IsLGA = false, Name = "Socket AM3", NumberOfPins = 941 }); cpuSockets.Add(new Objects.CPUSockets { IsLGA = false, Name = "Socket A", NumberOfPins = 462 }); jcWPLIBRARY.XML.XMLHandler<Objects.CPUSockets> xmlHandler = new jcWPLIBRARY.XML.XMLHandler<Objects.CPUSockets>(fileName: "cpusockets.xml"); var result = xmlHandler.WriteFile(data: cpuSockets); if (result.HasError) { MessageBox.Show(result.ErrorString); return; } MessageBox.Show("File written successfully"); [/csharp] Pretty simple, create your XMLHandler object using the inherited class previously and optionally pass in the filename you're going to want to later use. Note: You can pass in a different filename to the WriteFile function, by default it uses the constructor set filename however. The WriteFile function returns an XMLResult object. In this object you have a HasError property that if set to true, the ErrorString will contain exception text for you to read. This also applies to the ReadFile function mentioned below. The source code behind the Read XML Button: [csharp] jcWPLIBRARY.XML.XMLHandler<Objects.CPUSockets> xmlHandler = new jcWPLIBRARY.XML.XMLHandler<Objects.CPUSockets>(fileName: "cpusockets.xml"); var xmlresult = xmlHandler.LoadFile(); if (xmlresult.HasError) { MessageBox.Show(xmlresult.ErrorString); return; } StringBuilder stringBuilder = new StringBuilder(xmlresult.Result.Count()); foreach (var cpuSocket in xmlresult.Result) { stringBuilder.Append(cpuSocket.Name + " | " + cpuSocket.IsLGA + " | " + cpuSocket.NumberOfPins); } MessageBox.Show(stringBuilder.ToString()); [/csharp] Pretty simple hopefully. My next task (no pun intended) will be to add in support for Task-based Asynchronous Pattern (TAP) as everything I want to be doing going forward will be non-blocking. You can download the initial release of jcWPLIBRARY here. Or if you wish to also download the sample mentioned above, you can get it here. Note, the sample includes the library in the References folder so you don't need to download both to get started on your project with the library. Comments, suggestions whether they are positive or negative I would like to hear them.