woensdag 29 juni 2011

Using the codebehind in MVVM

Today I saw a topic on stackoverflow where a user asked a question on how to solve a certain piece of code that needed a UI element in MVVM.  Just an hour later a bunch of answers popped up telling him that it’s no problem putting this code in the code behind.  I disagree!

The piece of code the user was talking about was this:

xamDataGridExcelExporter.xamDataGridExcelExporter xamDataGridExcelExporter1 =      
new xamDataGridExcelExporter.xamDataGridExcelExporter();  
xamDataGridExcelExporter1.Export(this.xamDataGrid1,  
    @"C:\Excel\ExportFile.xls");

An argument to putting this kind of code in the code behind was that this is UI code.  UI code?  It’s not that because the Export method of XamDataGridExcelExporter accepts a UI element that it suddenly turned into UI code. 

When I see this piece of code I can think of a number of solutions that can isolate this piece of code from the UI.  We can for example inherit from XamDataGrid and make it responsible for its own export to excel.  Should the XamDataGrid be sealed then we can make a wrapper that does exactly the same thing.

So that just moves the problem you might think.  We still need a mechanism so the ViewModel can trigger this action.  This is where the Messenger class of MVVM light can be very handy.  On the initialization of the object we can register ourselves to a message and initiate our export action.   

Here is a quick example:

    public class XamDataGridWrapper : XamDataGrid
    {
        public XamDataGridWrapper()
            : base()
        {
            Messenger.Default.Register<string>(this, "ExportExcel", ExportFile);
        }

        private void ExportFile(string file)
        {
            xamDataGridExcelExporter.xamDataGridExcelExporter xamDataGridExcelExporter1 =      
            new xamDataGridExcelExporter.xamDataGridExcelExporter();  
            xamDataGridExcelExporter1.Export(this,  
                @"C:\Excel\ExportFile.xls");

        }
    }

The reason I would not encourage anyone for putting code in the codebehind unless it’s absolutely necessary is because of the broken window effect. A developer will see the code in the codebehind and quickly think, why not add a little more to make my life easy?  Granted that doing everything the MVVM way can be a brain teaser sometimes, but fragmenting your code between the ViewModel and the codebehind will give you more trouble than it’s worth afterwards.

To finish I’ll give a few examples in what (in my opinion are) cases you should use/not use the codebehind:
Not use codebehind:

  • Lack of dependency property
  • Invoking methods on a UI element
  • Laziness ;)
  •  
Use codebehind:
  • Interactive animations / storyboards (eg: animation based on mousespeed)
  • Accessing navigationservice
Till next time

woensdag 22 juni 2011

Changed Links

I've noticed there were problems with downloading the example files so I temporarly added them on my skydrive. I hope I can move them soon.

dinsdag 21 juni 2011

Book review: Clean Code

I just came back from holiday in Greece and I’ve read a couple of books there of which Clean Code is undoubtedly the most interesting one.  Here is a quick summary of what the book is about.

Clean Code is guide for developers that teaches you principles of how to make your code more readable and expressive.  It doesn’t really matter what language you program in as it applies on most modern OO programming languages.  I really learned allot from this book. While I was reading it I was cursing myself for breaking many of the rules layout by this book.   As the author of the book explains, this isn’t a feel good book that you can read once and then feel good that you’ve learned something.  It’s a continuing process of improving yourself and trying to express the requirements as clean as possible in code.  That is the reason that I’m planning on reading this book again, reading a chapter day by day to see what rules that I am breaking and how I can make my code more readable.

The author also does some bold things.  He, for example, takes a piece of OpenSource code and starts refactoring it piece by piece to make it clean.  By doing this you can see that clean code isn’t written from the first attempt but it is the process of writing dirty / “less clean” code then refining and molding it until it is readable.

The last chapter of the book covers code smells. The author admits borrowing a couple of the code smells from Refactoring of Martin Fowler. You can use this chapter as a checklist on a daily basis.  Once you see yourself breaking some rules you can start thinking about what you’re doing wrong and how you can refactor.

I could write pages about the many aspects this book covers so if you’re in to a very good book for writing code, then I recommend this one!  I’m also thinking about buying some of his other books like the The Clean Coder: A Code of Conduct for Professional Programmers (Robert C. Martin Series)  and  Agile Software Development, Principles, Patterns, and Practices 

To sum it up here are some of the things that sticked into the back side of my head:
  • Clean code doesn’t need allot of comments but comments itself
  • To write code you need to read code, so make sure that code is expressive and easy to read
  •  Boy Scout Rule: Leave the campground cleaner than you found it.
  • Treat your tests with the same care you treat your production code.  Rotting tests will lead to rotting production code
  • One assert per test
  • And many many more…
Until next time ;)


woensdag 1 juni 2011

XSLT transform your XML data into an OpenXml wordprocessing document


In this post I’ll explain to you how you can effectively and easily generate data into a OpenXml word-processing document.  I’m going to assume that you have some basic knowledge of OpenXml.  If you’ve been living under a rock for the last 6 years and don’t know what OpenXml is I gladly refer you to this PDFdocument.  It’s one of the best, if not the best, resources out there on OpenXml.

So to give you a basic Idea of what we are going to do I’ve drawn it in a little diagram:

 

We have basically 4 steps:
  1. We take our xml data and if there isn’t an XSD available then we create one
  2. With this XSD we start creating our template with CustomXml tags in them
  3. When the template is finished we run a tool to get a XSLT document that can generate our document
  4. We feed the XML data to the XSLT transformer and let it do its magic
1. Get the XSD 
Actually this step isn’t actually a step but more of a hint.  In the case you don’t have an XSD document for you XML data you can easily generate one with Visual Studio.  Just open up the XML document with Visual Studio and then go to the menu XML and select Create Schema.
 

 
2. Generate the template 
In order to do this I would recommend you to use Microsoft Word 2007 and above.  You COULD do this manually but since I’m very fond of my sanity I won’t do this.  Just create an empty word document in Word and see if you have the Developer ribbon.  If you don’t have the Developer ribbon then check here on how to make it appear.

In the developer ribbon go to Schema and import your XSD as I’ve did in the image.

 
In case you’re retarded: To import the schema you have to click ‘Add schema…’.

 
Select the option Allow saving as XML even if not valid.  I don’t know exactly why this has to be on but I’m guessing it has something to do with cross tagging of the custom XML tags.

Select you schema and then you can start editing you document!  Toggle the structure button in the ribbon next to the schema button.  This will give you a side panel which allows you to select the tags defined in your XSD.   

If you have sections you wish to generate per node then drag a selection around it and select the parent node.  As an example, in the image I will be generating the selected text PER customer.

You can apply this principle also on tables.  Here I generate a row PER product:

 

This is how the total document looks like:


When this is done, save the file as a Word 2003 XML document. Now I see you pondering: “huh wtf, I thought this was XSLT transformation with an OpenXml document???”.  Yes it still is but in disguise, I’ll explain in step 3.

3. Get the XSLT
Well you can do this is plenty of different ways.  If you’re really hardcore then you can write the XSLT yourself.  Send me a postcard from the mental institution when you’ve done this.  

The reason why I saved the OpenXml document as a word 2003 document is because I wanted to have the OpenXml package as a flat structured document.  What do I mean with that?  I want all the parts of the OpenXml package to be slammed into one XML document.  This off course has some disadvantages, performance being one of them.  

Once we have this we can feed this flat XML document to a tool called WML2XSLT .  The usage of this tool is as following:  

WML2XSLT.EXE TheTemplate.xml –o Generator.xslt.   

When the tool launches it gives you the option of selecting a namespace.  Select the namespace of you XSD:

  

After this the tool will have generated an XSLT for you!

4. Result
 All we have to do now is to transform our data XML document by applying the XSLT.  We can do this in code or with Visual Studio by selecting XML => Start XSLT (with/without debugging).  The result in my case looks something like this:

 
Now we have one small issue.  The result we have is an xml document, but we want a docx document so our customer is happy.  Well this is pretty easy to solve and I didn’t know about this since a couple of weeks ago when a colleague bumped into this.  You can create an empty package and add a part inside it of type chunck.  Then guess what this part is going to be?  Yes our flat chuncky document =) 
Here is an excellent link that will guide you through this:

using (WordprocessingDocument myDoc =
    WordprocessingDocument.Open("Test1.docx", true))
{
    string altChunkId = "AltChunkId1";
    MainDocumentPart mainPart = myDoc.MainDocumentPart;
    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
        AlternativeFormatImportPartType.WordprocessingML, altChunkId);
    using (FileStream fileStream = File.Open("TestInsertedContent.docx", FileMode.Open))
        chunk.FeedData(fileStream);
    AltChunk altChunk = new AltChunk();
    altChunk.Id = altChunkId;
    mainPart.Document
        .Body
        .InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());
    mainPart.Document.Save();
}

Voila that’s it.  Nothing to it!  You can find the files here.

Next blogpost will be in a couple of weeks because I’m going on a 2 week trip to rhodos now. Hell yeah! ;)