Friday, April 29, 2011

Getting the Most Out of the Winforms PropertyGrid Control in WPF

The PropertyGrid control has been missing in WPF since it's release and sadly it's still missing! There have been various attempts by third parties to provide one and I cant speak for the commercial offerings but I find the ones in the open source space to be quite lacking and incomplete. Most projects I found on codeplex are still in beta!

I really like the api exposed by the original PropertyGrid which I have been using for years now but it's a Winforms control. This presents some problems. The main issue for me with the Winforms version of the PropertyGrid is that it's not styleable. So it means that I'll have some inconsistency in my UI and it will stick out as shabby and odd.

Below is a screenshot of the PropertyGrid bound to a simple “Person” object, that exposes a complex type Address and a vehicle collection property.


As old as it may look, it works so well and does it job so nicely! I love this control. In the end, I've decided to use this in my Wpf application regardless of the oddity it brings. Clearly, functionality is a lot more important and since beauty lies in the eyes of the beholder, it's a subjective matter. And writing a brand new native Wpf PropertyGrid control is out of the question.

Looks apart, think of the great things this control can do. You practically bind your objects to it and it will list them in a neat grid, categorized, with many builtin editors for color editing, navigating for images, browsing and editing collections using the builtin CollectionEditor etc. And if this is not enough you can write simple extensions with your own custom editors. Indeed this control is a gem!
Update 4/30/2011
It seems since we are referencing a Winforms library, in particular System.Windows.Forms, our client app is forced to reference the fatter .NET 4.0 version versus just the slimmer .NET 4.0 client profile which is the default. 
It's not such a big con, but most certainly something to consider. I've left some more instructions at the bottom of this post.
One thing in particular that I've done is to wrap it up in a Custom Wpf Control because in order to use the Winforms version in Wpf, we'll need to :
  1. Interop via WindowsFormsHost (as easy as eating cake)
  2. We'd like to bind our ViewModel to the PropertyGrid directly from the View declaratively. This will allow us to avoid tight coupling with our ViewModel.
Here's what the custom controls template looks like :

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:WpfLab2.Controls"
                   xmlns:o="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms">
    <Style TargetType="{x:Type local:WpfPropertyGrid}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:WpfPropertyGrid}">
                    <Grid>
                        <WindowsFormsHost x:Name="host">
                            <o:PropertyGrid x:Name="propertyGrid1"/>
                        </WindowsFormsHost>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Minus the namespaces and the common style declarations you'll likely do for any templating requirement, it's fairly simple. All we need is to nest the Winforms PropertyGrid inside a WindowsFormsHost.

<Grid>
    <WindowsFormsHost x:Name="host">
        <o:PropertyGrid x:Name="propertyGrid1"/>
    </WindowsFormsHost>
</Grid>

That's pretty much all of the code. Simple indeed. The Wpf Control itself consists of a single dependency property minus a small plumbing effort. Attached to this article I include a sample application containing the control, so you can get a hang of how it works. Our View itself that consumes the PropertyGrid, just comes down to a single line of code that includes the Custom control binding to a property in the ViewModel declaratively eg:

 <local:WpfPropertyGrid SelectedObject="{Binding PersonItem, Mode=TwoWay}" />

See! Now powered with such a fantastic control you can provide easy editing of objects in your application and maintain your MVVM pattern. I love it.

Make sure you also read the following resource on msdn if your new to the PropertyGrid. It provides all the basics you'll need to know to get you up and running quickly.

http://msdn.microsoft.com/en-us/library/aa302326.aspx (Basics about the PropertyGrid)
http://msdn.microsoft.com/en-us/library/ms742875.aspx (About hosting winforms in wpf)

The sample application included is a basic example using a single person object that in turn has a complex property and a collection property. Once you edit the properties and hit the Ok button, it will display the changes in the object via a messagebox.

Nothing fancy, but you can see some simple mvvm, creation of a simple custom value converter for the complex type “Address” exposed as a property and a the creation of a simple collection editor to allow editing the “Vehicles” collection property. Just enough to get you started.

Update: 4/30/2011
A gotcha I forgot to mention is that you'll have to reference System.Windows.Forms which resides in the System.Windows.Forms assembly. The PropertyGrid control resides in this dll. When trying to reference this library from the project references dialog, you won't find it in the list of available dlls. That's because by default your project is using the .Net 4.0 client profile, so go in your project properties window and change it from .Net 4.0 client profile to .Net 4.0. After this step you can try referencing the dll again and it will be in the list.

The Microsoft .NET Framework 4 Client Profile provides a subset of features from the .NET Framework 4. The Client Profile is designed to run client applications and to enable the fastest possible deployment for Windows Presentation Foundation (WPF) and Windows Forms technology. Application developers who require features that are not included in the Client Profile should target the full .NET Framework 4 instead of the Client Profile.
Update: 5/25/2011
I was able to change the target framework back to the default Client profile after referencing System.Windows.Forms ; It seems this is already in the Client profile. What will throw you off is if your referencing System.Design.dll which will require the Full version of .NET. One typical requirement will arise for you when developing custom TypeEditors because most of the existing type editors are in the System.Design dll. Still thankfully, my needs for custom type editors was pretty basic and I got away developing one from scratch ( inheriting TypeEditor).

I found that not setting height and width explicitly for the control makes its load time slow and at most awkward even. The fix is to be explicit with the height and width. This must be due to layout differences between WPF and Windows Forms. The following article on msdn has the meat and potatoes.

http://msdn.microsoft.com/en-us/library/ms744952.aspx

So, in case its not clear, when using the control, this is what you want to attempt :

<my:WpfPropertyGrid SelectedObject="{Binding PersonItem}" Width="290" Height="350">
            </my:WpfPropertyGrid>

Notice the explicit Width and Height above. Now the speed should be super fast! Keep reading the article on msdn I link to above, it has some pretty good information.

And a small correction to the article, it's not entirely true that you cannot style the property grid. You can do some basic styling of the Winforms PropertyGrid. What you cannot do is enjoy a complete designer experience like you can currently with WPF controls. So, it's not as traggic as I made it sound.

Download the sample application

Tuesday, April 26, 2011

Custom popup and windows in WPF the MVVM way

In WPF, using the regular window control to launch child windows makes MVVM and separating a View concern from the ViewModel very difficult.

The problem:
The window control works nicely as a shell for your application, however, launching child windows is problematic because the window control cannot be defined in xaml unless as the root element.
So, if you wanted to launch child windows inside a parent window, you lose the ability to declare these in xaml. This loss means you will not be able to bind to properties in your ViewModel from the view for the purpose of opening/closing a window. Instead you end up doing this imperatively in code which means more code, more thought, more work.

Following is what you end up doing in the most minimalistic cases.

MyWindow window = new MyWindow();
window.ShowDialog();

Adding code such as the above means you are forced to make your ViewModel create instances of your Window and launch them when needed. Clearly something you will not appreciate during testing and since this will provide a tight coupling to a Window control in your ViewModel, it is useless to your tests and eventually breaks your pattern.

What would have been nice instead is if we could do the following :

<my:ModalDialogPopup IsOpen="{Binding FirstPopupIsOpen, Mode=TwoWay}"/>

If we could define our window declaratively in Xam as above, then we use the databinding capabilities in WPF and bind to an FirstPopupIsOpen property in our ViewModel, which is what we are after but sadly not currently possible.

The solution 1: A custom Control that behaved like a Window
Writing a custom control was pretty simple as we make use of the existing Popup control in Wpf. The popup control is pretty wild and requires taming but solves this problem.

Some reasons to design our solution around the existing Popup control:
  1. The popup control is designed to stay always ontop, which has it's pitfalls but it solves more problems than it brings. More specifically we will want the ability to hide the content under the popup while the popup is in view.
  2. The popup control can be positioned in so many ways, however what we are after is the ability to define a set of Left, Top coordinates and this is supported out of the box.
  3. The popup control supports a few animations out of the box. This means we can apply a nice sliding or a fade effect with zero effort.
  4. The popup control can contain child controls obviously. This is great and serves our purpose very well.
  5. Enjoy the beauty of an adorner masking the background beneath the ModalDialogPopup.
The solution we end up with is a control like the following :

<my:ModalDialogPopup IsOpen="{Binding FirstPopupIsOpen, Mode=TwoWay}">
            <my:ModalDialogPopup.HostedContent>
                <ContentControl>
                    <Grid Height="200" Width="300">
                        <TextBlock VerticalAlignment="Center" 
                             HorizontalAlignment="Center" FontSize="20">
                            This is the first modal popup
                        </TextBlock>
                    </Grid>
                </ContentControl>
            </my:ModalDialogPopup.HostedContent>
        </my:ModalDialogPopup>

One inherent problem I had not considered while writing this control is that just like the Window control, even with a custom popup control, the limitation to not being able to nest a popup in another popup existed. That's because when showing the child, we are forced to hide the parent for technical reasons that exist in the popup control only(the popup control will always be the top most control).

That means if the parent is larger than the child in dimention, portions of controls in the parent will show and interaction with those pieces becomes possible. When a child popup is launched, we want it to behave as a modal window, so it shouldn't be able to interact with controls in popups beneat it. Sadly the adorner cannot help us here as it cannot cover the “Always ontop” popup.


Ofcourse, the solution to deal with this limitation is to hide the parent when the child is in view, which doesn't help the nesting because if the parent is hidden, then the child will be hidden too! I guess there is a good reason why the Window control in WPF does not allow nesting! Too bad I had to discover this at my own expense.

Even with this shortcomings, in most cases, you can workaround the nesting limitation by designing your solutions with this drawback in mind.

As you can note from the piece of xaml code in the previous code listing above, we have a control that can be defined in our view declaratively that takes content via the HostedContent template. We can also set a Title, and content in it's HostedContent template. In the previous code listing, everytime the property FirstPopupIsOpen evaluates to “true” in our ViewModel, the popup will open.

By default the custom popup provides an OK and Cancel button whose caption/visibility you can set. If you need more customizations you can very well customize its template by providing a custom style. Attemping to supply custom styling is quite simple because the default markup we use is plain and this is intentional since styling is subjective and a trival matter. This enables you to provide custom styling of your own without fighting your way through heavy use of xaml.

If you take a look at the code listing below, all we have is a 3 row grid, one holding the title, the second holding the content you define in the HostedContent template and the last row to hold the OK and Cancel buttons. Simply put, you are in control of the styling and the default style template is prive of any bloated styling markup to distract you.

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:WpfPopup.Controls">
    <Style TargetType="{x:Type local:ModalDialogPopup}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate 
                     TargetType="{x:Type local:ModalDialogPopup}">
                    <Popup x:Name="dialog" AllowsTransparency="True">
                        <Grid x:Name="content">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="20"/>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="20" />
                            </Grid.RowDefinitions>
                            <TextBlock Grid.Row="0" x:Name="title" />
    <!-- the hosted content -->
                            <ContentPresenter x:Name="contentHost" 
                                Grid.Row="1" Margin="5"/>
                            <StackPanel Grid.Row="2" Orientation="Horizontal" 
                                HorizontalAlignment="Right">
                                <Button Content="Ok" x:Name="buttonOK" 
                                  MinWidth="100" Margin="0,0,5,0" />
                                <Button Content="Cancel" x:Name="buttonCancel" 
                                   MinWidth="100" Margin="0,0,5,0" />
                            </StackPanel>
                        </Grid>
                    </Popup>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

And here it is when popped open in the example solution attached to this post :


It's actually quite a minimal control without any bells and whistles and leave the responsibility of styling it in your hands, any way you want. Notice the adorner masking the background and the convenient Ok/Cancel buttons. It's so much simpler to use and easy to test. The amount of work need to set this up compared to a window control (solution 2 below) is minimal.

Surely there is some value for such a control but it is most definitely not a resonable replacement to the Window control entirely, as far as launching child windows is concerned.

Fortunately, the needed work to decouple the existing Window control from the ViewModel could very well be done with a simple interface contract, which brings us to the next solution.

Solution 2 : Decoupling the Window control from the ViewModel
This solution relies on dependency injection to provide proper decoupling of the Window control from the viewmodel. So, we'll need a dependency injection container. You may use any at this point, I'll be using Microsofts Unity. This will also make it a breeze to inject a stub in place of the Window control when Unit testing.

First, let's look at what we're going to construct. It's going to be a series of dialogs. The main Window, and 2 child windows.

The main window :

A child window launched from the main window above :


And finally another child window launched from the child window above :

Ok, now that we know what we are building, lets start. The procedure is simple. We'll start by defining the common functionality we'd normally use from the Window Control in our ViewModel by throwing it into an interface.

public interface IChildWindow
{
 void Close();
 bool? ShowDialog();
 void SetOwner(object window);
 bool? DialogResult { get; set; }
}

We do this for each View that is a window control. The reason is simple, in order to decouple the window from the viewmodel, what we are going to do is use constructor injection. By injecting this dependency in the constructor we can ensure easy substitution with fake stubs during testing and everything will just work.

Let's also decouple the window we plan to launch by adding yet another interface :
public interface IChildWindowNested
{
 void Close();
 bool? ShowDialog();
 void SetOwner(object window);
 bool? DialogResult { get; set; }
}

And finally, the viewmodel:

public class ChildWindowViewModel
{
 private readonly IChildWindow _childWindow;
 private readonly IChildWindowNested _childWindowNested;
 private ICommand _okCommand;

 private ICommand _openCommand;

 public ChildWindowViewModel(IChildWindow childWindow,
    IChildWindowNested childWindowNested)
 {
  _childWindow = childWindow;
  _childWindowNested = childWindowNested;
 }

 public ICommand OpenCommand
 {
  get
  {
   return _openCommand ?? (_openCommand =
    new DelegateCommand(OpenClick));
  }
 }

 public ICommand OkCommand
 {
  get
  {
   return _okCommand ?? (_okCommand =
    new DelegateCommand(OkClick));
  }
 }

 private void OpenClick()
 {
  _childWindowNested.SetOwner(_childWindow);
  _childWindowNested.ShowDialog();
 }

 private void OkClick()
 {
  _childWindow.DialogResult = true;
  _childWindow.Close();
 }
}

As you can notice in the above class, we are passing 2 interfaces in the constructor. The first is the window using this viewmodel : ChildWindow.xaml and the second is the window it will launch : ChildWindowNested.xaml

The relationship between these two windows is a typical parent child relationship, ChildWindow.xaml is the parent, while ChildWindowNested.xaml is the child being launched.

The reason we pass IChildWindow, the parent window in this case is because :
  1. We need to tell the child Window we are launching who it's owner is. That way we can nicely position the child window relative to it's parent.
  2. As this is the viewmodel of ChildWindow.xaml, we will also want to handle closing this parent window when it's Ok and Cancel buttons are clicked.
The reason we pass IChildWindowNested, the child window we are launching is because:
  1. We want to launch this dialog based on an action in ChildWindow.xaml
  2. To decouple the window from the viewmodel, because we will be using dependency injection to set up this dependency on the window control.

Now the codebehind for ChildWindow.xaml :

public partial class ChildWindow : Window, IChildWindow
{
 private readonly IUnityContainer _container;

 public ChildWindow()
 {
  InitializeComponent();
  _container = UnityContainerResolver.Container;
  var childWindowNested = 
                             _container.Resolve<IChildWindowNested>();

  DataContext = new ChildWindowViewModel(this
                                                childWindowNested);
  Closing += ChildWindowClosing;
 }

 #region IChildWindow Members

 public void SetOwner(object window)
 {
  Owner = window as Window;
 }

 #endregion

 private void ChildWindowClosing(object sender, CancelEventArgs e)
 {
  e.Cancel = true;
  Visibility = Visibility.Hidden;
 }
}

We can setup the viewmodel binding to the DataContext in several ways however doing this in the codebehind of the view as in the sample code above is the most flexible of all solutions especially if your moving beyond the typical blog post samples.

At the end of the day, it's only a matter of opinion and what's important is that there is no dependency impeding you from testing your application. And ofcourse that it does not break your pattern. In our case, it's both convenient as we want to pass a reference of the current window to the viewmodel and at the same time, we want to do it in a very decoupled way to help us test our viewmodel.

Also note that we are hooking into the closing handler and cancelling the default close behavior of the Window control. That's because once a window is closed, we cant reopen it and we'll need to create a new instance of the window.
Certainly this depends on your use case. For me, my requirements are such that I need to reuse the window being closed. This works nicely.

What about dependency injection and how is our Unity container setup ? It's quite simple in this case. For this sample code, I just created a singleton that registers all dependencies with the container :

public class UnityContainerResolver
{
 private static IUnityContainer _container;

 private UnityContainerResolver()
 {
 }

 public static IUnityContainer Container
 {
  get
  {
   if (_container == null)
   {
    _container = new UnityContainer();
    RegisterTypes();
   }
   return _container;
  }
 }

 static void RegisterTypes()
 {
  _container.RegisterType<IMainWindow, MainWindow>();
  _container.RegisterType<IChildWindow, ChildWindow>();
  _container.RegisterType<IChildWindowNested, 
                                                    ChildWindowNested>();
 }
}

That's it. By registering dependencies with a dependency container, it becomes so easy to inject fakes in our viewmodel in place of the real object. In our case, when testing, we can make a different registration by mapping to our fake mock objects and this is relatively simple when using a dependency container :

static void RegisterTypes()
{
 _container.RegisterType<IMainWindow, MockMainWindow>();
 _container.RegisterType<IChildWindow, MockChildWindow>();
 _container.RegisterType<IChildWindowNested, 
                                  MockChildWindowNested>();
}

And MockChildWindow having enough code to satisfy the contract of IChildWindow.

public class MockChildWindow : IChildWindow
{
 public object Owner { get; set; }
 public void Close()
 {
  //
 }

 public bool? ShowDialog()
 {
  return true;
 }

 public void SetOwner(object window)
 {
  Owner = window;
 }

 public bool? DialogResult
 {
  get;
  set;
 }
}

The viewmodel itself only uses methods exposed by the contract so we are safe to use a fake object as above for testing.

I have added a test app containing the custom popup and all code discussed here. Be sure to check it out!
Download sample application

Thursday, April 21, 2011

Display and Editor Templated View Helpers in ASP.NET MVC

Templated view helpers simplify your work greatly by allowing you to specify that rendering is required for display or input via Display and Editor templated Helpers respectively without needing to explicitly specify what Html element to map the properties to, in our model.

For example, given the following controller that is passing a model to the view :

// Get: /Home/Edit/1
public ActionResult Edit(int id)
{
 var p = GetPerson(id);
 return View(p);
}

Now, without resorting to Templated View Helpers, in order to display our model for edit, in the view we can attempt to offload the task of rendering an appropriate Html element for a property in our model to a View Helper :

@model MvcLab.Models.Person

@{
    ViewBag.Title = "Edit a person";
}

@using (Html.BeginForm()) {
    @Html.TextBox(Model.FirstName);
}


in the above example, Html.TextBox will output :

<input id="FirstName" name="FirstName" 
       type="text" value="Alessandro" />



By using the Html.TextBox helper, we were able to specify explicitly what input element we wanted mapped to a property in our model.

This is nice but we've had to explicitly state that we wanted a TextBox mappped to the FirstName field.

The same can be achieved by using Templated View Helpers which are yet a more convenient way to associate an Html element to a property in our model :

@using (Html.BeginForm()) {
    @Html.EditorFor(x => x.FirstName);
}

The above piece of code will also render an Html input element :

<input class="text-box single-line" 
      id="FirstName" name="FirstName" type="text" value="Alessandro" />

The output is pretty much the same, but notice that we didn't explicitly state what element to associate to the FirstName property. How this works is that it bases its assumption on the data type of the property and whatever model attribute meta data decorations set on it.

In ASP.NET MVC 2 onwards, there are 3 Editor Helpers that do the same thing with slight differences in usage. @Html.Editor, @Html.EditorFor and @Html.EditorForModel, the first can take a string containing our property name and the second a strongly typed model to property mapping expression and the third will just use the strongly typed model passed to the view by default.

They each provide some flexibility how the Editor Template View Helper is used. We'll be using @Html.EditorFor and @Html.EditorForModel for the remainder of this post.

The following piece of code in the view uses EditorForModel.

@model MvcLab.Models.Person

@{
    ViewBag.Title = "A person";
}

@using (Html.BeginForm()) {
    @Html.EditorForModel();
<p><input type="submit" value="Save" /></p>
}

<p>
    @Html.ActionLink("Back to List", "Index")
</p>

Something as simple as @Html.EditorForModel(); will output an input element for each property in our model. Notice how we didn't loop nor needed to pass the model. Since we're passing the Model in the view, using the default no arguments overloads works just nicely. The above piece of code in the view will output to screen :


While this renders our model, we can see that the output needs a bit more tweaking, for example the field labels are using the property name, this can be tweaked on the model itself using attribute decorations such as :

[DisplayName("First name")]
public string FirstName { get; set; }

Next, the id field is displaying. We'd rather this was not displayed, as this too can be compensated for by providing another attribute decoration on the property such as :

[HiddenInput(DisplayValue = false)]
public int PersonId { get; set; }

Completed person class after the noted changes :

public class Person
{
 [HiddenInput(DisplayValue = false)]
 public int PersonId { get; set; }
 [DisplayName("First name")]
 public string FirstName { get; set; }
 [DisplayName("Last name")]
 public string LastName { get; set; }
 public Address Residence { get; set; }
}

This renders as below :



That's much better, yet now we can note that our complex property Residence, which is a class with its own set of properties, did not render. In order to fix this we can try the following :

@using (Html.BeginForm()) {
    @Html.EditorForModel();
 @Html.EditorFor(x => x.Residence);
<p><input type="submit" value="Save" /></p>
}

<p>
    @Html.ActionLink("Back to List", "Index")
</p>

While this is all great and works by convention, we do eventually lose fine grained control over how each field is rendered in the end. One option is to go back to rendering each field individually eg: @Html.EditorFor(x => x.FirstName) directly in the view, but then if we need to reuse this model in another view, we keep repeating each field over and over again. The extra code in each view also begins to weigh on us and becomes unmaintainable sooner than later.

One way to solve this is to move the logic into a Partial view which can then be reused in a single line of code on other views where we'd want to render a Person model. An even nicer approach is to use convention, again designating Editor and Display templates for our Templated View Helpers. Using this approach will result in providing us with fine grained control over the output. Lets try that now.

Instead of creating the rendering for our model in the view directly, lets move it to a partial view. Following convention for Templated View Helpers, the partial view (template) needs to be stored in the following locations :
/Views/Shared/DisplayTemplates/TemplateName.cshtml and /Views/Shared/EditorTemplates/TemplateName.cshtml.

And since our model is a Person object, we will name our template Person.cshtml for both Display and Editor templates. This is to follow convention as that is the template it will look for based on the type name. There is still more flexibility in defining a template by using meta data attributes UIHint and passing a template name there or by passing a template explicitly in the Templated View Helper itself.

To keep the post simple we are going to use only default convention and setup custom EditorTemplates as the procedure is the same for DisplayTemplates. Along with the article I've included a sample application that shows usage for both Display and Editor templates.

/Views/Shared/EditorTemplates/Person.cshtml :

@model MvcLab.Models.Person

@Html.ValidationSummary(true)
<fieldset>
    <legend>Person</legend>

    @Html.HiddenFor(model => model.PersonId)

    <div class="editor-label">
        @Html.LabelFor(model => model.FirstName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.FirstName)
        @Html.ValidationMessageFor(model => model.FirstName)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.LastName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.LastName)
        @Html.ValidationMessageFor(model => model.LastName)
    </div>
</fieldset>

<!-- Note that the Residence property is a complex type for whom
 we've defined a template too in : Views\EditorTemplates\Address.cshtml -->
 @Html.EditorFor(model => model.Residence)

and now a Template for Address, though we could have done it in the Person object itself, as this gives us the flexibility of reusing the Address models rendering in any view.

/Views/Shared/EditorTemplates/Address.cshtml

@model MvcLab.Models.Address

    <fieldset>
        <legend>Address</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.City)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.City)
            @Html.ValidationMessageFor(model => model.City)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Country)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Country)
            @Html.ValidationMessageFor(model => model.Country)
        </div>
    </fieldset>

Note that, upto this point, we have not written a single line of code. What we see so far is all auto generated scaffolding when electing to set a strongly typed class on a partial view in Visual Studio itself. This is much quicker and we're left with remodeling the markup to fit our design requirements.

Below is a screenshot of the Add View dialog that we've used to autogenerate most of the code above.



Next, we are finally ready to reuse these templates in our views :

/Views/Home/edit.csHtml

@model MvcLab.Models.Person

@{
    ViewBag.Title = "Edit a person";
}

@using (Html.BeginForm()) {
    @Html.EditorForModel();
<p><input type="submit" value="Save" /></p>
}

<p>
    @Html.ActionLink("Back to List", "Index")
</p>


Note that the code in our view and every other view that wants to reuse the Person model has gone down to a single method call : @Html.EditorForModel()

and the output :




Final conclusions :
As we have seen, by using Templated View Helpers, we were able to promote reusability of our models rendering and in the process we were not limited by typical black box solutions as we were able to gain fine grained control by defining custom templates for our models.

Best yet, we followed convention over configuration and ended up doing little work with improved productivity and maintainability of our code. Following the same procedure here on this post, we can define custom templates for Display View Helpers too in the same way we provided templates for Editors.

The sample application provided along with this post defines templates for both Display and Editor Helpers.

This is what it all looks like in solution explorer :

Sample application : download
Reference material :
http://msdn.microsoft.com/en-us/library/ee402949.aspx
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.uihintattribute.aspx

Tuesday, April 19, 2011

MARS - Multiple Active Result Sets support in SQL Server 2005 and above

SQL Server 2005 onwards supports MARS - Multiple Active Result Sets. MARS enables you to reuse an existing connection to perform operations on SQL Server. This makes MARS a viable alternative to server-side cursors with significant performance boosts. As powerful that may seem it has it's drawbacks so care needs to be taken when using it.


Here's an example from msdn:

SqlCommand cmd = conn.CreateCommand();
SqlCommand cmd2 = conn.CreateCommand();
cmd.CommandText = @"select operation_id, operation_code, product_id, quantity 
      from dbo.operations where processed=0";
cmd2.CommandText = @"update dbo.operations set processed=1 
      where operation_id=@operation_id";
SqlParameter opid=cmd2.Parameters.Add("@operation_id", SqlDbType.Int);
reader=cmd.ExecuteReader();
while (reader.Read())
{
   ProcessOperation();
   opid.Value=reader.GetInt32(0); // operation_id
   //notice how we are trying to execute an update query on the second command
   //this is going to fail miserably because
   //we did not set MutipleActiveResultSets=Yes 
   //on the connectionstring
   cmd2.ExecuteNonQuery();
}

By default MARS is not enabled. So reusing the same connection as the example above will throw an exception of type :

InvalidOperationException, There is already an open DataReader associated with this Connection which must be closed first.

Say hello to MARS :

Enabling usage of MARS is as simple as setting MultipleActiveResultSets=Yes on your connectionString, eg:

<connectionStrings>
    <clear />
      <add name="TyppsDB" 
         connectionString="Data Source=typps-pc;Initial Catalog=TyppsDB;
                 Integrated Security=True;MultipleActiveResultSets=Yes" />
 </connectionStrings>

you can now issue multiple commands on the same connectionstring which can result in a performance boost since opening and closing a connection can be expensive.

When retrieving recordsets, the client has to eager load, meaning consume the resultsets immediately as oppossed to executing the command and not reading the data. Not doing so will cause the server-side buffer(Where sql server is hosted) to hold on to the data in memory and tie up resources, locks, threads etc something you want to avoid.

Instead you want the data to stream to the client as fast as possible as the server returns the resultset without the server holding a large recordset in memory and tying up resources. This is not specific to MARS by the way, but when used correctly with eager loading meaning you consume the data as the command is executed  you can benefit from a significant performance boost as you have the ability to execute more commands and retrieve data seamlessly without the overhead of closing and reopening a connection to Sql Server.

myReader = myCommand.ExecuteReader(); while(myReader.Read())
{
 //consume immediately now, don't wait.
}

Any command that is a SELECT, FETCH, READTEXT, RECEIVE, BULK INSERT (or bcp interface) or Asynchronous cursor population can take full advantage of MARS.

What this means is that with MARS enabled, each of these commands listed above are defined in terms of interleaved executions, allowing them to be processed atomically within the same connection but with the ability to interleave, this means they can resume execution from the points where they were suspended if at all suspended.

For instance, INSERT and UPDATE cannot take advantage of MARS. Now, consider a long running INSERT or UPDATE operation followed by a SELECT statement, all executing within the same connection. Such an operation will suspend the SELECT command until the UPDATE or INSERT has completed and then resume the SELECT operation.

Consider reversing the above example where you had a SELECT followed by an UPDATE or INSERT operation within the same connection. Even in this case, if the UPDATE or INSERT command are issued while the SELECT is executing, then the SELECT command will interleave and as such become suspended until the INSERT or UPDATE complete and only after completion of the UPDATE or INSERT operation, will it resume execution.

This is because the SELECT command can take advantage of MARS and has the ability to resume from the point where it was suspended making it an interleaved execution.

Lastly, note that there are some intricacies when using transactions with MARS. You will need to workaround using recommendations provided eg: by using batch-scoped transactions.

References :
http://msdn.microsoft.com/en-us/library/ms345109(v=sql.90).aspx
http://msdn.microsoft.com/en-us/library/ms174377.aspx