Friday, February 24, 2012

MVVm - Embed C# code in XAML like ASP.Net MVC

It is long time since I posted something in this blog. I know this is my most famous blog with average 200hits/day but I was mainly concentrating into the other aspects of .Net such as CLR, WCF, ASP.Net, Windows Phone 7 etc than this XAML based display technology. There are 2 main inspirations for this post.

First one is a comment which I got on my post related to opacitymask and its usage in WPF. The specialty of that is, it came from a MSFT guy. I don't know how others are thinking, but for me its little important. Even I am not sure whether that MSFT is just something else or that person just added MSFT :-)

The second reason is "This is my 100th post on WPF technology and I want that to be something special and useful". I was in search for such a topic and just found today, while I was working with ASP.Net MVC 3 application.

The problem
Anyway I am not wasting time on introduction.Lets come to the topic. As everybody knows MVVm is the widely accepted pattern for the XAML based technologies such as WPF and Silverlight. The main reason I could see is the data binding support. By design the pattern is not expecting anything in the code behind and everything related to business should reside in the viewmodel. Its all fine.We can have data binding and commands to separate the view from vm. But what can I do with the dialogs? Since they are UI is that desirable to call showdialog from viewmodel or should I write code behind for views and pass the dialog result to vm through event aggregator or any other messaging mechanism? Mainly this comes into picture when we need to browse for a file or show a messagebox in MVVm based application.

There are something called behaviors and triggers in an expression blend dll named System.windows.interactivity which we can leverage to accomplish the same. But are there any better way? Yes another way is to call the ShowDialog from the vm itself and process it. This is what I was following till I came to play more with ASP.Net MVC pattern.

What is special with ASP.Net MVC
MVC is another UI pattern to separate the UI from its business. When Microsoft implemented a framework to write asp.net applications using the same, people started calling it as ASP.Net MVC. Actually there is no relation between ASP.Net and MVC .Anybody can implement MVC in their application without MSFT framework.

The specialty I noticed in MVC framework is, there is no option to write code behind. In the RAZOR view we cannot even find a code behind file. I wondered how people are accomplishing their tasks without writing the code behind for views. Theoretically we can say "don't write code behind" .But I have never seen a big enterprise application in MVVm without code behind for at least one view.Coming back to ASP.Net MVC, the RAZOR don't give us option to write code behind but provides support to embed code inside the view itself.
Yes the idea flashed in my head and I could recollect one of my old post which explains embedding code    inside the xaml file .That is the way to handle the dialog boxes better.

Solution : Embed C# or VB.Net code in xaml view
This doesn't mean we should move the code behind file into the view. This helps to write the dialog handling code in the view itself. Below is one example of such an implementation.


    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <TextBox x:Name="txtFileName"
                 Text="{Binding FilePath,UpdateSourceTrigger=PropertyChanged}" />
        <Button Grid.Column="1" Content="Browse" Click="Clicked" />
        <x:Code>
            <![CDATA[
void Clicked(object sender, RoutedEventArgs e)
{
            Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
            ofd.DefaultExt = ".exe";
            ofd.Filter = "Executables (.exe)|*.exe"; // Filter files by extension

            // Show open file dialog box
            Nullable<bool> result = ofd.ShowDialog();
            // Process open file dialog box results
            if (result.HasValue && result.Value)
            {
                // Set value to textbox which will update the property of VM
                txtFileName.Text= ofd.FileName;
            }
}
]]>
        </x:Code>
        <Button Content="Start"
                Grid.Column="2"
                Command="{Binding StartCommand}" />
    </Grid>

Pros and Cons
One thing to notice is that we need to give name to the controls which other developers may use to write code behind.Next thing how to show a message dialog box in this way .For that we need to keep a property in the vm and bind to a hidden textbox . Wire the TextChanged event of textbox to an event handler in the view as how the above C# code is written .
Main development challenge will be how to write code without intellisense .Yes you don't get intellisense when writing code inside xaml file.One way to overcome is to write the code in normal file and copy paste.