Wednesday, December 21, 2011

Upgrading Nuget 1.5 to 1.6 - Installation error

If you have the Nuget 1.5 extension installed, your Visual Studio (VS 2010) will prompt to update to Nuget 1.6 version. If you try to update to Nuget 1.6, you might run into installation error. If so, uninstall the older version - Nuget 1.5 and then try installing the new version - Nuget 1.6. In order to uninstall Nuget, you need to run the VS 2010 in "administrator" mode.


For more details view the release notes here.

Monday, December 19, 2011

C# extension method - OrderBy sort expression as string

Recently I came across a question in a forum where a part of the solution requires the sort expression as string type for the OrderBy extension method. The requirement is, upon passing a string of property name separated by comma, the respective sort need to be applied and returned.

Without explaining further, directly I dive into the implementation so that you can easily infer from that. I altered the snippet got from http://www.extensionmethod.net/Details.aspx?ID=124 based on our needs.

Snippet 1 (Core extension method for OrderBy and ThenBy)

public static class IEnumerableExtensions
{
    public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> list, string sortExpression)
    {
        sortExpression += "";
        string[] parts = sortExpression.Split(' ');
        bool descending = false;
        string property = "";

        if (!(parts.Length > 0 && parts[0] != ""))
        {
            throw new Exception("Invalid sort expression.");
        }

        property = parts[0];

        if (parts.Length > 1)
        {
            descending = parts[1].ToLower().Contains("esc");
        }

        PropertyInfo prop = typeof(T).GetProperty(property);

        if (prop == null)
        {
            throw new Exception("No property '" + property + "' in + " + typeof(T).Name + "'");
        }

        if (descending)
            return list.OrderByDescending(x => prop.GetValue(x, null));
        else
            return list.OrderBy(x => prop.GetValue(x, null));
    }

    public static IOrderedEnumerable<T> ThenBy<T>(this IOrderedEnumerable<T> list, string sortExpression)
    {
        sortExpression += "";
        string[] parts = sortExpression.Split(' ');
        bool descending = false;
        string property = "";

        if (!(parts.Length > 0 && parts[0] != ""))
        {
            throw new Exception("Invalid sort expression.");
        }

        property = parts[0];

        if (parts.Length > 1)
        {
            descending = parts[1].ToLower().Contains("esc");
        }

        PropertyInfo prop = typeof(T).GetProperty(property);

        if (prop == null)
        {
            throw new Exception("No property '" + property + "' in + " + typeof(T).Name + "'");
        }

        if (descending)
            return list.ThenByDescending(x => prop.GetValue(x, null));
        else
            return list.ThenBy(x => prop.GetValue(x, null));
    }

    public static IEnumerable<T> OrderByStringExpression<T>(this IEnumerable<T> queryObj, string orderByProperties)
    {
        if (string.IsNullOrWhiteSpace(orderByProperties))
        {
            //throw new Exception("Invalid sort expression");
            return queryObj;
        }

        string[] orderByPropertyArray = orderByProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
        IOrderedEnumerable<T> orderedItem = null;

        if (orderByPropertyArray.Length > 0)
        {
            orderedItem = queryObj.OrderBy(orderByPropertyArray[0]);

            if (orderByPropertyArray.Length > 1)
            {
                for (int i = 1; i < orderByPropertyArray.Length; i++)
                {
                    orderedItem = orderedItem.ThenBy(orderByPropertyArray[i]);
                }

            }
        }

        return orderedItem;
    }
}

Snippet 2 (Example code)

var sortResult = listInst.OrderByStringExpression("Id,Name desc");

As you see, each property name should be separated by comma and if required you can specify the sort mode (asc/desc) followed by a blank space with the respective parameter.

Now with the above specified method, we can pass simple comma separated string as sort expression and get the related instance sorted. This will helpful in scenarios like implementing the Repository pattern as I did here.  Hope this helps.

References
http://www.extensionmethod.net/Details.aspx?ID=124





Sunday, December 4, 2011

Windows Phone 7.1 - Things to know about Dormant and Tombstone states

In WP 7.1, if we click on the start button when an application is running, the application will have the Deactivated event got fired. Usually developers will save any application state in this event handler into the application level dictionary object represented through the PhoneApplicationService.State property and make use of it in the Activated state again.

After the Deactivated event got invoked, the application which is in running state is moved to the Dormant state. Most developers get this state unnoticed. In this Dormant state, application still remain in memory but without processing happen and without application getting terminated. Based on the memory resource requirements for other applications, the application in the Dormant state has the possibility to get into the Tombstone state. The Tombstone state for an application represents the application as terminated, in the meantime, it holds the state info of the application. By state info we mean, the application state which is represented through the PhoneApplicationService.State property (as specified above) and the page state which is represented through PhoneApplicationPage.State property.

The main thing we need to notice is the reactivation scenario of an application. The application might get  reactivated from both the states directly. In both the cases, it raises the Activated event, where we need to identify whether the application is activated from the Tombstone state. If so, we can get values from the application level state dictionary (PhoneApplicationService.State) and make use of it. If it was from Dormant state, we don't need to do anything as the OS automatically preserves the state.

Since both scenarios raises the Activated event, there needs to be a mechanism to identify whether the immediate previous state is Dormant or Tombstone state. It is the IsApplicationInstancePreserved property of the ActivatedEventArgs which helps us to achieve this. As you might guess, if the IsApplicationInstancePreserved is true then it was from Dormant state and if it is false, then it was form Tombstone state.

While debugging your application you can validate both these Dormant and Tombstone state scenarios by clicking on the start button of your emulator when your application is running . When you click on the start button of the emulator, by default, the application will move to the Dormant state. If you want to validate the Tombstone state, check the "Tombstone upon deactivation while debugging" check box in the Debug tab of the project properties.

Following snippet helps you to understand handling of Dormant and Tombstone states:

Snippet 1 (App.xaml.cs)

private void Application_Launching(object sender, LaunchingEventArgs e)
{
    Debug.WriteLine("Application launching event");
}

private void Application_Activated(object sender, ActivatedEventArgs e)
{
    Debug.WriteLine("Application activated event");
    
    if (e.IsApplicationInstancePreserved)
    {
        Debug.WriteLine("Application activated from Dormant state....");
    }
    else
    {
        Debug.WriteLine("Application activated from Tombstone state.....");
    }
}

private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
    Debug.WriteLine("Application deactivated event");
}

private void Application_Closing(object sender, ClosingEventArgs e)
{
    Debug.WriteLine("Application closing event");
}

Saturday, November 19, 2011

ScrollToBottom extension method in ScrollViewer - Silverlight 4

ScrollViewer is one among the commonly used Silverlight control. When you develop Silverlight application, at some time, you'll come across using ScrollViewer. Using ScrollViewer is straightforward in most of the cases. In some scenarios (like displaying chat history messages, stock history update), we might want to bind values to elements inside the ScrollViewer and then scroll to the bottom in order to make the latest message appear in the visible region.

ScrollToBottom() is one among the several extension methods available for ScrollViewer which helps us to achieve scrolling vertically to the end of the ScrollViewer content. While using this ScrollToBottom() method some developers won't see the ScrollViewer scrolls upto the bottom. So, why it is like that what need to be done to make it work? Let us dive into the implementation of ScrollToBottom() method and find out the solution.

Snippet 1: (ScrollToBottom() implementation)

public static void ScrollToBottom(this ScrollViewer viewer)
{
    if (viewer == null)
    {
        throw new ArgumentNullException("viewer");
    }

    viewer.ScrollToVerticalOffset(viewer.ExtentHeight);
}

As most of us might guess, it scrolls the veritical offset to the height of the content inside the ScrollViewer. Actually the values for properties like ScrollViewer.ExtentHeight, ScrollViewer.VerticalOffset are not recalculated immediately. It seems that they placed such restrictions due to performance considerations.

We can force to recalculate and update values of related properties by calling the UpdateLayout() method of the ScrollViewer. Anyhow be sure to call the UpdateLayout() only required. Please view the remarks section here at msdn documentation.

Ultimately, calling the UpdateLayout() method on the ScrollViewer before ScrollToBottom() is called will solve the obstacle.

Following is a sample snippet to help you understand the above specified scenario. Try executing the following snippet and inspect the value of ExtentHeight(and related properties) property by inserting the breakpoint in the call to UpdateLayout() method.

Snippet 2:
ScrollViewerTest.xaml

<UserControl x:Class="TestSilverlightApplication1.ScrollViewerTest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="500" d:DesignWidth="500">
    <Grid Background="DeepSkyBlue">
        <Grid x:Name="LayoutRoot" Background="SkyBlue" Height="300" Width="400">
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="70"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="70"></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <StackPanel>
                <TextBlock Text="ScrollToBottom Check" HorizontalAlignment="Center" FontWeight="Bold" ></TextBlock>

            </StackPanel>
            <TextBlock Grid.Row="1" Text="Enter multiline text here......"></TextBlock>
            <ScrollViewer Grid.Row="2">
                <TextBox AcceptsReturn="True" Text="{Binding SampleTextString, Mode=TwoWay}"></TextBox>
            </ScrollViewer>
            <Button Content="...and click here...." Click="ScrollDownCheck_Click" Width="150" Grid.Row="3" Margin="10"></Button>
            <ScrollViewer Grid.Row="4" Name="TestScrollControl">
                <TextBox AcceptsReturn="True" Name="TestTextBox" Text="{Binding AlteredTextString}"></TextBox>
            </ScrollViewer>
        </Grid>
    </Grid>
</UserControl>


ScrollViewerTest.xaml.cs

using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;

namespace TestSilverlightApplication1
{
    public partial class ScrollViewerTest : UserControl, INotifyPropertyChanged
    {
        public ScrollViewerTest()
        {
            InitializeComponent();
            InitControls();
        }

        private string sampleTextString;

        public string SampleTextString
        {
            get { return sampleTextString; }
            set
            {
                sampleTextString = value;
                NotifyPropertyChanged("SampleTextString");
            }
        }

        private string alteredTextString;

        public string AlteredTextString
        {
            get { return alteredTextString; }
            set
            {
                alteredTextString = value;
                NotifyPropertyChanged("AlteredTextString");
            }
        }
         
        private void ScrollDownCheck_Click(object sender, RoutedEventArgs e)
        {
            ManipulateScrollDownCheck();
        }

        private void InitControls()
        {
            this.DataContext = this;
        }

        private void ManipulateScrollDownCheck()
        {
            this.AlteredTextString = this.SampleTextString;
            //Insert breakpoint here and validate the value of 
            //ExtentHeight before and after the execution of UpdateLayout().
            TestScrollControl.UpdateLayout();
            TestScrollControl.ScrollToBottom();
        }

        #region INotifyPropertyChanged Members

        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}


You can infer from the above example that the call to UpdateLayout() is made before calling ScrollToBottom() and after assinging the value to the property bound to the content(UIElement contained inside the ScrollViewer) of the ScrollViewer. Since developers will face such problem only at certain workflows, call the UpdateLayout() only when you encounter that problem.

Reference
http://msdn.microsoft.com/en-us/library/system.windows.controls.scrollviewer.scrolltoverticaloffset(v=vs.95).aspx
http://msdn.microsoft.com/en-us/library/system.windows.controls.scrollviewer.scrolltobottom.aspx
https://epiinfo.svn.codeplex.com/svn/Silverlight.Controls.Toolkit/Controls.Toolkit/Common/ScrollViewerExtensions.cs

Sunday, November 13, 2011

n layer web app with Entity Framework 4.1/4.2 - Things to consider

With Entity Framework 4.1, it releases DbContext API and CodeFirst development model. It is recommended to work with DbContext which exposes the commonly used features of ObjectContext.
Creating object context in DatabaseFirst or ModelFirst approach can be done with the help of ADO.NET DbContext Genrator template in Visual Studio. To achieve that open the .edmx file and right click the base surface >> Add Code Generation Item >> Code >> ADO.NET DbContext Generator. This template is available only when you install EF 4.1 directly. If you install the EF4.1 with NuGet packages, the reference will get added but the ADO.NET DbContext Generator template won't be available. You can use NuGet packages for adding(and managing) the reference to the specific project or solution.

Repository pattern suits best for this case, so that we can create an individual repository for each entity. For details on repository pattern please visit msdn() and Martin Fowler's explanation. Following is a simple and common representation of repository that developers adopt using EF4.1. Please note that following snippet is just to understand the concept.

Snippet 1

public class CompanyRepository: IDisposable
{
    private HSMDBEntities Context { get; set; }

    public CompanyRepository()
    {
        this.Context = new HSMDBEntities();
    }

    public void Create(Company company)
    {
        this.Context.Companies.Add(company);
        this.Context.SaveChanges();
    }

    public Company GetCompanyById(int id)
    {
        //this.Context.Companies.Load();
        //return this.Context.Companies.Where(c => c.Id == id).Single();
        return this.Context.Companies.Find(id);
        
    }

    public IEnumerable<Company> GetAll()
    {
        return this.Context.Companies.ToList();
    }
    
    public void Update(Company company)
    {
        Company currentEntry = this.Context.Companies.Where(c => c.Id == company.Id).First();

        //Client wins model.
        this.Context.Entry(currentEntry).CurrentValues.SetValues(company);
        this.Context.SaveChanges();
    }

    public void Remove(Company company)
    {
        Remove(company.Id);
    }

    public void Remove(int id)
    {
        Company currentEntry = this.Context.Companies.Where(c => c.Id == id).Single();
        this.Context.Companies.Remove(currentEntry);
    }

    public void Dispose()
    {
        this.Context.Dispose();
    }
}

The above Repository snippet exposes the basic operations performed over the entity. Most of the methods are straight forward to understand and the two methods we need to concentrate are GetCompanyById() and Update().

GetCompanyById()  - The DbSet<T> property of the DbContext instance exposes a Find method which uses the primary key to find the entity. The speciality of this method is that the database will be hit only if the entity with the specific key is not found in the context. If the specific entity already got loaded, that entity will be returned upon request without hitting the database. That's why I've commented out the default way of retrieving the entity.

Update() - Consider the following scenario. In n layer architecture, the data model/entity retrieved will be converted into domain specific model and other DTOs(Data Transfer Objects), while passing across the layer to reach the client application(like web app). Similarly the modified data from the client reaches the data tier passing several transitions, and we simply update the database with the values from client. If any other request updates some column value of the entity in the interim time, those changes won't be respected, and whatever value reaches the data tier is updated in a brutal manner. This approach is called as client wins approach which is used common among n layer web applications. I restrict myself ending this update scenario with this short detail as this discussion itself can extend as a separate article. This client wins model is achieved in the above snippet by fetching the current status from the database and overwriting the values got from the client and continue saving it. The highlight here is the SetValues() method of the property DbPropertyValue, which assigns all the current values of individual properties with that of the properties of the parameter object supplied to it. This eradicates the great work of reassigning the individual property values explicitly.

this.Context.Entry(currentEntry).CurrentValues.SetValues(company);


in the place of

var entityEntry = this.Context.Entry(currentEntry);
entityEntry.Property(p => p.Id).CurrentValue = 1;
entityEntry.Property(p => p.CompanyName).CurrentValue = "Company name altered";

 

Now comes the reason for implementing the IDisposable. The best practice regarding the creation of DbContext instance when handling with a web application is - one context instance per request. Hence in n layer web application architecture, components in other layer(most of the times will be Business components) should take the responsibility of handling the lifetime of the context. This can be achieved by handling the respective repository instance with the using construct which automatically calls the dispose method of the repository instance.

using (CompanyRepository companyRepository = new CompanyRepository())
{
...............................
}


In real cases a base and a generic repository will be created based on the project nature and repository  created for each entities will be extended from the base repository. At that situation the base repository class will implement the IDisposable which handles the context instance creation and its lifetime.

public class CompanyRepository : BaseRepository
{        
    public CompanyRepository()
        :base()
    {
        
    }

    public void Create(Company company)
    {
        this.Context.Companies.Add(company);
        this.Context.SaveChanges();
    }

    public Company GetCompanyById(int id)
    {
        //this.Context.Companies.Load();
        //return this.Context.Companies.Where(c => c.Id == id).Single();
        return this.Context.Companies.Find(id);

    }

    public IEnumerable<Company> GetAll()
    {
        return this.Context.Companies.ToList();
    }

    public void Update(Company company)
    {
        Company currentEntry = this.Context.Companies.Where(c => c.Id == company.Id).First();

        //Client wins model.
        this.Context.Entry(currentEntry).CurrentValues.SetValues(company);
        this.Context.SaveChanges();
    }

    public void Remove(Company company)
    {
        Remove(company.Id);
    }

    public void Remove(int id)
    {
        Company currentEntry = this.Context.Companies.Where(c => c.Id == id).Single();
        this.Context.Companies.Remove(currentEntry);
    }

}

public class BaseRepository : IDisposable
{
    protected HSMDBEntities Context { get; set; }

    public BaseRepository()
    {
        this.Context = new HSMDBEntities();
    }

    public void Dispose()
    {
        this.Context.Dispose();
    }
}


The BaseRepository also need to be extended further. Its good to have the above things in mind while developing n layer web application. 

Saturday, October 29, 2011

ASP.NET MVC 3 - Representing contents in Razor View

The Razor view engine in ASP.NET MVC 3, throws error when we specify the content block directly without enclosing it in tags especially inside the coding constructs like if, for loop and so on.

Following Snippet throws error
@if(condition) {
    Any direct content.......
}


In such cases, developers usually specify tags like <span> as a workaround in order to specify the contents. But there exists two ways for directly represent this case.
  1. @: - for indicating the characters following it are content items and usually used for representing single line content.
  2. <text>....</text> - entire content block is enclosed within the <text>....</text> element and usually used for representing multi line contents.

@if(condition) {
    <text>Multi line statement 1
    Multi line statement 1
    ..................
    Multi line statement n</text>
}


@if(condition) {
    @:single line content goes here....
}


This is a straight forward feature but unexposed to several developers. It is simple but effective.

Sunday, October 23, 2011

Parsing and Manipulating HTML strings - C#

Recently I came across a situation, where I need to retrieve an HTML string created and stored by an ASP application. Upon retrieving the html string, I need to parse the string and manipulate html string by removing some deprecated attributes and us some other equivalent alternate instead. For instance the size attribute in the font element need to be replaced with css font-size attribute.

Snippet 1:

<font size="1">......</font>

to 

<font style="font-size: 9px;">......</font>


One additional thing we need to note here is, since we don't have any direct equivalent of the unit and value for the size attribute, I simply changed it to the expected size for the invoking applications.

Fine, now comes core of the issue about how to manipulate the HTML string. Initially I thought of using regex. Suddenly, I remembered of the nice tool Html Agility Pack which I explored few months back. Its an HTML parser that allows us to select an HTML element and manipulate it very easily. It uses the XPath to navigate through the elements. If you don't know XPath, no problem. You can refer to examples over the net (like in msdn and w3schools ) and find the XPath that suits better your requirement in less than a minute.

Following is the code for the situation I mentioned above.
Snippet 2:

private string RestructureDeprecatedAttributes(string htmlText)
{
    HtmlDocument document = new HtmlDocument();
    HtmlNodeCollection fontNodeCollection;
    
    document.LoadHtml(htmlText);
    fontNodeCollection = document.DocumentNode.SelectNodes("//font[@size]");

    if (fontNodeCollection != null)
    {
        foreach (HtmlNode fontNode in fontNodeCollection)
        {
            HtmlAttribute sizeAttribute = fontNode.Attributes["size"];

            if (!string.IsNullOrWhiteSpace(sizeAttribute.Value) && int.Parse(sizeAttribute.Value) > 0)
            {
                if (sizeAttribute.Value.Equals("1"))
                {
                    fontNode.SetAttributeValue("style", "font-size: 9px;");
                }
                else
                {
                    fontNode.SetAttributeValue("style", "font-size: 11px;");
                }
                
                fontNode.Attributes["size"].Remove();
            }
        }
    }

    return document.DocumentNode.WriteTo();
}

The selectors are really powerful which allows us to select the nodes that perfectly matches our criteria. The Html Agility Pack provides several methods that supports the manipulation of HTML strings in a very easy manner. You can infer this from the above code.

Sunday, October 9, 2011

ASP.NET MVC - Html.Partial vs Html.RenderPartial

RenderPartial writes the result directly to the response, technically speaking, directly into the calling object's TextWriter.

Partial on the other hand returns the HTML markup as string, which buffers the content. It achieves by creating and using a separate TextWriter.

Syntactic representation:
RenderPartial should be used inside a code block (obviously followed by a semicolon).

@{
    Html.RenderPartial("TestPartialView1");
}

Partial can be used directly as it returns the HTML markup as string.

@Html.Partial("TestPartialView1")

Usage:
Considering the performance RenderPartial is a bit faster and hence developers prefer using it inside the looping constructs and related scenarios.

Preference of Partial prevails in the case of regular syntax usage(meaning - uniform syntax usage as we don't need to wrap inside the code block) and if we need to perform any manipulation with the resultant HTML markup string.

Monday, September 12, 2011

ASP.NET MVC 3 - jQuery template tag inside Url.Action method

In this post we're going to deal with handling the jQuery template tag inside the Action method of the UrlHelper class(Url.Helper). To get a basic idea on jQuery templates and its implementation in ASP.NET MVC 3, have a glimpse on my previous posts ASP.NET MVC 3 and jQuery templates part1 and part2. Also for easier understanding I'll be using the same example explained in the post part2.

Let us consider a scenario to display list of members in a table format where each row represents each member and their related details represented in the subsequent columns. Let the final column represent a view hyperlink which onclick calls the action method MemberDetails of the ProjectMemberDetails with the id(EmployeeId) as parameter.

So our focus is to create a hyperlink with href something like "..../ProjectMemberDetails/MemberDetails/E1001", where "E1001" corresponds to the employee id. Also note that my map route is specified in such a way that the URL accepts id parameter.

Snippet 1: (Global.asax.cs - Default map route)

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

Following is my controller holding the related actions.

Snippet 2: (Controller)

public class ProjectMemberDetailsController : Controller
{
    public ActionResult ProjectMemberListForTemplateCheck(string experience)
    {
        return View("JqueryTemplateTagInAction");
    }

    [HttpPost]
    public JsonResult ProjectMemberListForTemplateCheckJson(string experience)
    {
        SampleData sampleData = new SampleData();

        if (string.IsNullOrEmpty(experience) || experience.Equals("All"))
        {
            return Json(sampleData.ProjectMemberList, JsonRequestBehavior.AllowGet);
        }
        else
        {
            return Json(sampleData.GetProjectMembersWithExpGreaterThan(int.Parse(experience)), JsonRequestBehavior.AllowGet);
        }
        
    }

    public ActionResult MemberDetails(string id)
    {
        SampleData sampleData = new SampleData();

        return View("MemberDetails", (object)sampleData.GetProjectMemberDetails(id));
    }
}

Snippet for SampleData is same as in ASP.NET MVC 3 and jQuery templates part2.

Now just concentrate on the template part for building the hyperlink.

Snippet 3: (template part with template tag inside @Url.Action(....))

<script id="memberDetailTemplate" type="text/x-jquery-tmpl">
    <tr>
        <td>
            ${EmployeeName}
        </td>
        <td>
            ${Experience}
        </td>
        <td>
        {{if Designation == 'Tech Lead'}}
        <span style="color:Green; font-weight: bold;">${Designation}</span>
        {{else}}
        <span style="color:Blue;">${Designation}</span>
        {{/if}}            
        </td>
        <td style="text-align:center;">
            <a href="@Url.Action("MemberDetails", "ProjectMemberDetails", new { id = "${EmployeeId}" })">View</a>
        </td>
    </tr>  
</script>


The idea is when the view engine renders the page, the href should be rendered like "..../ProjectMemberDetails/MemberDetails/${EmployeeId}", which on applying templ function with data, the "${EmployeeId}" should be replaced with the employee id.

Upon executing the application with the above template as specified in the Snippet 3, the href is rendered as "..../ProjectMemberDetails/MemberDetails/%24%7BEmployeeId%7D".

What went wrong here? Have close look again. Yes, the string "${EmployeeId}" is url encoded and represented as is, which the jQuery template (.tmpl method)  is unable to detect and parse it. So once the specific part of the URL is rendered as "${EmployeeId}" instead of "%24%7BEmployeeId%7D", the jQuery template will parse and evaluate the template tag correctly and we'll get the expected result.

In order to achieve this, we need to apply the url decode(for attaining the reverese effect) over the resultant url action(Url.Action(....)).

Snippet 4:

<a href="@HttpUtility.UrlDecode(Url.Action("MemberDetails", "ProjectMemberDetails", new { id = "${EmployeeId}" }))">View</a>


Following is the full version of the code.

Snippet 5:

@model string
@{
    ViewBag.Title = "Jquery template tag inside Url.Action";
}
<h2>
    Jquery template tag inside Url.Action</h2>
@if (false)
{
    <script type="text/javascript" src="../../Scripts/jquery-1.6.2-vsdoc.js"></script>
}
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>

<script type="text/javascript" src="@Url.Content("~/Content/MVC3TestApp2/Scripts/jquery.tmpl.js")"></script>
<script id="memberDetailTemplate" type="text/x-jquery-tmpl">
    <tr>
        <td>
            ${EmployeeName}
        </td>
        <td>
            ${Experience}
        </td>
        <td>
        {{if Designation == 'Tech Lead'}}
        <span style="color:Green; font-weight: bold;">${Designation}</span>
        {{else}}
        <span style="color:Blue;">${Designation}</span>
        {{/if}}            
        </td>
        <td style="text-align:center;">
            <a href="@HttpUtility.UrlDecode(Url.Action("MemberDetails", "ProjectMemberDetails", new { id = "${EmployeeId}" }))">View</a>
        </td>
    </tr>  
</script>
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax({ type: "POST", url: '@Url.Action("ProjectMemberListForTemplateCheckJson", "ProjectMemberDetails")', success: jsonProjectMemberListSuccessCallback });
    });

    function jsonProjectMemberListSuccessCallback(data) {
        var targetElement = $('#memberData');
        targetElement.empty();

        $("#memberDetailTemplate").tmpl(data).appendTo('#memberData');
    }
</script>
<div id="loadingFeedback" style="display: none; color: Red; font-weight: bold;">
    <p>
        Loading details....
    </p>
</div>
@using (Ajax.BeginForm(new AjaxOptions
{
    LoadingElementId = "loadingFeedback",
    OnSuccess = "jsonProjectMemberListSuccessCallback",
    Url = Url.Action("ProjectMemberListForTemplateCheckJson", "ProjectMemberDetails")
}))
{
    <table border="1" cellpadding="0" cellspacing="0" >
        <thead>
            <tr>
                <th>
                    Member Name
                </th>
                <th>
                    Experience
                </th>
                <th>
                    Designation
                </th>
                <th>
                    View Details
                </th>
            </tr>
        </thead>
        <tbody id="memberData">
        </tbody>
    </table>
    <p>
        @Html.Label("", "Member with experience greater than : ")
        @Html.DropDownList("experience", new SelectList(new[] { "All", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, (Model ?? "All")))
        <input type="submit" name="Submit" value="Submit" />
    </p>   
     
}

Saturday, August 20, 2011

ASP.NET MVC 3 updating and handling the jQuery libraries

When installing the ASP.NET MVC 3, we'll be getting some tools for Visual Studio 2010 along with Nuget.Nuget is nothing but an Visual studio extension which can be used to install and update open source libraries. It handles the task of including the library files into the project, adding the required references, including the respective entries in the config files and some other tasks based on the package we install.

We can access the Nuget tools using Visual Studio 2010 from, Tools > Library Package Manager > Package Manager Console / Manage Nuget Packages. One we add the ASP.NET MVC 3 project to a solution, by default we'll get few jQuery and related packages got installed.

Package Manager Console
We can view the installed packages by typing the "get-package" command in the Package Manager Console. By default jQuery packages like jQuery (core library), jQuery.UI.Combined, jQuery.Validation and jQuery.vsdoc will be installed while adding the ASP.NET MVC 3 project. In order to update these default jQuery packages, use the following command in the Package Manager Console.

update-package jquery

In order to get info about Nuget Package Manager commands type "get-help nuget".    

Manage Nuget Packages
Apart from the Tools menu this option is also avaliable when we right click(context menu) on the project. This option is some what similar to the Extension Manager menu where we can visually manage the packages.



Summary
Using any of the above specified two options you can update the packages which will update the related files by removing the old ones and adding the new ones. This helps us handling the updating process smoothly without any miss-outs.

Monday, August 15, 2011

ASP.NET MVC - Identifying the nature of request using IsAjaxRequest()

HttpRequestBase class is provided with an extension method called IsAjaxRequest() which specifies whether the request has been initiated as an AJAX call/request. Actually it looks for a specific header (x-requested-with: XMLHttpRequest) in the HTTP request made and acts accordingly.

From the Controller class we can access this method using Request.IsAjaxRequest(), as the Request property holds/gets the HttpRequestBase object for the current HttpRequest.

Ok, now let us see the real use of this IsAjaxRequest() method. If you see the ProjectMemberDetailsController in my previous post ASP.NET MVC 3 and jQuery templates - Part2, I've used two methods ProjectMemberList() and ProjectMemberList(string experience) with [HttpPost] attribute. Each serves the following purpose: 
  1. ProjectMemberList() - Called when the view is rendered initially by the view engine. Here we need to return the related view and this is a non-AJAX call by nature.
  2. ProjectMemberList(string experience) [HttpPost] - Invoked whenever the AJAX call is initiated using POST request. Here we need to return the JSON result.
 With the help of IsAjaxRequest(), let us see how can we change the ProjectMemberDetailsController.

Snippet 1 (ProjectMemberDetailsController with IsAjaxRequest())

public class ProjectMemberDetailsController : Controller
{
    public ActionResult ProjectMemberList(string experience)
    {
        SampleData sampleData = new SampleData();

        if (Request.IsAjaxRequest())
        {
            if (string.IsNullOrEmpty(experience) || experience.Equals("All"))
            {
                return Json(sampleData.ProjectMemberList, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(sampleData.GetProjectMembersWithExpGreaterThan(int.Parse(experience)), JsonRequestBehavior.AllowGet);
            }
        }

        return View();
    }
}

Summary
From the above snippet we can clearly infer that how effectively we can utilize the IsAjaxRequest() method. It'll be very much helpful and can be used effectively in lot of scenarios. One such scenario I faced is while customizing the Authorize attribute, in order to determine the authorization logic based on the nature of the request.

References
http://msdn.microsoft.com/en-us/library/system.web.mvc.ajaxrequestextensions.isajaxrequest.aspx

Sunday, August 14, 2011

ASP.NET MVC 3 and jQuery templates - Part2

In part 1, we saw the basic implementation of jQuery template with the help of html file. In this part we'll look into a simple implementation using ASP.NET MVC 3. Following few steps will define the steps I've followed to create the sample which helps readers to dive into the code with better understanding.

First created an empty ASP.NET MVC3 web application. Then created a model by adding an Employee class in the Models folder.

Snippet 1(Model - Employee)

public class Employee
{
    public string EmployeeId { get; set; }
    public string EmployeeName { get; set; }
    public int Experience { get; set; }
    public string Designation { get; set; }
}

For the purpose of this example have created a SampleData class in the Models folder.

Snippet 2 (SampleData)

public class SampleData
{
    #region Class Level Variables
    private List<Employee> projectMemberList;
    #endregion

    #region Properties
    public List<Employee> ProjectMemberList
    {
        get
        {
            if (projectMemberList == null)
            {
                LoadProjectMemberList();
            }
            return projectMemberList;
        }
        set { projectMemberList = value; }
    }
    #endregion

    #region Public Methods
    public IEnumerable<Employee> GetProjectMembersWithExpGreaterThan(int experience)
    {
        return ProjectMemberList.Where(emp => emp.Experience > experience);
    }
    #endregion

    #region Private Methods
    private void LoadProjectMemberList()
    {
        projectMemberList = new List<Employee>();

        projectMemberList.Add(new Employee { EmployeeId = "E1001", EmployeeName = "Member1", Experience = 7, Designation = "Project Lead" });
        projectMemberList.Add(new Employee { EmployeeId = "E1002", EmployeeName = "Member2", Experience = 4, Designation = "SSE" });
        projectMemberList.Add(new Employee { EmployeeId = "E1003", EmployeeName = "Member3", Experience = 9, Designation = "Tech Lead" });
        projectMemberList.Add(new Employee { EmployeeId = "E1004", EmployeeName = "Member4", Experience = 3, Designation = "SE" });
        projectMemberList.Add(new Employee { EmployeeId = "E1005", EmployeeName = "Member5", Experience = 5, Designation = "Team Lead" });

    }
    #endregion

}

Next in the Controllers folder have created a ProjectMemberDetailsController.

Snippet 3 (ProjectMemberDetailsController)

public class ProjectMemberDetailsController : Controller
{
    
    public ActionResult ProjectMemberList()
    {
        return View();
    }

    [HttpPost]
    public JsonResult ProjectMemberList(string experience)
    {
        SampleData sampleData = new SampleData();

        if (string.IsNullOrEmpty(experience) || experience.Equals("All"))
        {
            return Json(sampleData.ProjectMemberList, JsonRequestBehavior.AllowGet);
        }
        else
        {
            return Json(sampleData.GetProjectMembersWithExpGreaterThan(int.Parse(experience)), JsonRequestBehavior.AllowGet);
        }

    }
}

Finally added a ProjectMemberList.cshtml file under the Views/ProjectMemberDetails folder.

Snippet 4 (ProjectMemberList)   

@model String
@{
    ViewBag.Title = "ProjectMemberList";
}
<h2>
    ProjectMemberList</h2>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js"
    type="text/javascript"></script>

<script id="memberDetailTemplate" type="text/html">
    <tr>
        <td>
            ${EmployeeName}
        </td>
        <td>
            ${Experience}
        </td>
        <td>
        {{if Designation == 'Tech Lead'}}
        <span style="color:Green; font-weight: bold;">${Designation}</span>
        {{else}}
        <span style="color:Blue;">${Designation}</span>
        {{/if}}            
        </td>
    </tr>  
</script>
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax({ type: "POST", url: "ProjectMemberDetails/ProjectMemberList", success: jsonProjectMemberListSuccessCallback });
    });

    function jsonProjectMemberListSuccessCallback(data) {
        var targetElement = $('#memberData');

        targetElement.empty();

        $("#memberDetailTemplate").tmpl(data).appendTo('#memberData');
    }
</script>
<div id="loadingFeedback" style="display: none; color: Red; font-weight: bold;">
    <p>
        Loading details....
    </p>
</div>
@using (Ajax.BeginForm(new AjaxOptions
{
    LoadingElementId = "loadingFeedback",
    OnSuccess = "jsonProjectMemberListSuccessCallback",
    Url = Url.Action("ProjectMemberList")
}))
{
    <table border="0" cellpadding="0" cellspacing="5">
        <thead>
            <tr style="font-weight: bold;">
                <td>
                    Member Name
                </td>
                <td>
                    Experience
                </td>
                <td>
                    Designation
                </td>
            </tr>
        </thead>
        <tbody id="memberData">
        </tbody>
    </table>
    <p>
        @Html.Label("", "Member with experience greater than : ")
        @Html.DropDownList("experience", new SelectList(new[] { "All", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, (Model ?? "All")))
        <input type="submit" name="Submit" value="Submit" />
    </p>   
   
}

The ProjectMemberList view will automatically use the /Views/Shared/_Layout.cshtml as the layout/master page which is specified in the /Views/_ViewStart.cshtml file.

In order to run invoke the specific action by default, have modified the RegisterRoutes method of MvcApplication class in the Global.asax.cs file as follows:

Snippet 5 (Default Route - Global.asax.cs)

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "ProjectMemberDetails", action = "ProjectMemberList", id = UrlParameter.Optional } // Parameter defaults
    );

}

After doing the above changes, when the application is run, the URL ProjectMemberDetails/ProjectMemberList is invoked which in turn invokes the ProjectMemberList action in the ProjectMemberDetailsController. The ProjectMemberList() action returns the related view and this execution happens when the page is first rendered. When the page is rendered, the script we specified in the $(document).ready(...); will be executed. Since we've made a jQuery AJAX call over there with type "POST" and URL("ProjectMemberDetails/ProjectMemberList"), it causes an AJAX call over our action ProjectMemberList(string experience) with attribute [HttpPost] which returns the required result in JSON format. The jQuery script, handles the returned result with the success callback method we specified, which renders the data using the jQuery template on the client side.

The main thing need to be noted is the ProjectMemberList(string experience) action in the ProjectMemberDetailsController which returns the result in the JSON format(JsonResult). Also our view is designed in such a way that the specific action is invoked only using the AJAX call.

You might have also observed that, a predefined dropdown list and a submit button are accompanied inside the AJAX Form represented by @using (Ajax.BeginForm(..)){...} with relevant AjaxOptions as parameter. This AJAX Form ensures that every submit made through the Form will be made as AJAX request. Hence if any submit is made through the submit button click, the ProjectMemberList action specified in the AjaxOptions is invoked passing the option selected in the dropdown list. It is the ASP.NET MVC framework that renders the parameter value, since the parameter specified is same as the name of the dropdown list.

Summary
As a general practice, in the above specified scenarios, the first time when the view is rendered (as the AJAX call won't happen), we'll be using the partial view for rendering the templated region and as we used AJAX Forms, further submit will be directed as AJAX calls. But here, I've specified an example of making an AJAX request from jQuery inside the $(document).ready(...);, because several developers having questions about raising the AJAX request during the initial rendering of the view, which is also answered here.

References
http://api.jquery.com/jQuery.ajax/


Update - 05Nov2011 (Representing the implementation with {{each}} template tag and handling date)

Based on the question asked, I'll specify the modification need to be done to the snippets above in order to see the implementation of {{each}} template tag and displaying date values.

Scenarios included : Have added two more columns Technical Expertise and Date of Joining for display and modified the sample data based on that.
In the case of technical expertise, I receive the list of string values and display each item in the list inside the div element.
In the case of joining date, the received date need to be converted to Date() type in javascript and then formatted accordingly. There exists several ways to achieve that. For this sample I'll use the way specified in one of the stackoverflow.com questions. Here are the refered links - http://stackoverflow.com/questions/206384/how-to-format-a-json-date and http://blog.stevenlevithan.com/archives/date-time-format.

Following are the changes need to be done in the above specified snippets to view the updated example.

Changes in Snippet 1(Model - Employee)
Add two more properties.

public class Employee
{
    public string EmployeeId { get; set; }
    public string EmployeeName { get; set; }
    public int Experience { get; set; }
    public string Designation { get; set; }
    public List<string> TechnicalExpertise { get; set; }
    public DateTime JoiningDate { get; set; }
}

Changes in Snippet 2 (SampleData)
Alter the LoadProjectMemberList methods as follows.

private void LoadProjectMemberList()
{
    projectMemberList = new List<Employee>();

    projectMemberList.Add(new Employee { EmployeeId = "E1001", EmployeeName = "Member1", Experience = 7, Designation = "Project Lead", TechnicalExpertise = new List<string> { "ASP.NET", "C#", "Silverlight" }, JoiningDate = DateTime.Now.AddYears(-4) });
    projectMemberList.Add(new Employee { EmployeeId = "E1002", EmployeeName = "Member2", Experience = 4, Designation = "SSE", TechnicalExpertise = new List<string> { "ASP.NET", "C#" }, JoiningDate = DateTime.Now.AddYears(-2) });
    projectMemberList.Add(new Employee { EmployeeId = "E1003", EmployeeName = "Member3", Experience = 9, Designation = "Tech Lead", TechnicalExpertise = new List<string> { "ASP.NET", "C#", "Silverlight" }, JoiningDate = DateTime.Now.AddYears(-6) });
    projectMemberList.Add(new Employee { EmployeeId = "E1004", EmployeeName = "Member4", Experience = 3, Designation = "SE", TechnicalExpertise = new List<string> { "ASP.NET", "VB.NET" }, JoiningDate = DateTime.Now.AddYears(-3) });
    projectMemberList.Add(new Employee { EmployeeId = "E1005", EmployeeName = "Member5", Experience = 5, Designation = "Team Lead", TechnicalExpertise = new List<string> { "ASP.NET", "C#" }, JoiningDate = DateTime.Now.AddYears(-4) });

}

Changes in Snippet 4 (ProjectMemberList)
Download and add the "date.format.js" file from http://blog.stevenlevithan.com/archives/date-time-format. Then add the script reference in the page.
In our case it is


<script type="text/javascript" src="@Url.Content("~/Content/MVC3TestApp2/Scripts/date.format.js")"></script>

Replace the related matching items with the following snippets.
Replacement 1:

<script id="memberDetailTemplate" type="text/html">
    <tr>
        <td>
            ${EmployeeName}
        </td>
        <td>
            ${Experience}
        </td>
        <td>
        {{if Designation == 'Tech Lead'}}
        <span style="color:Green; font-weight: bold;">${Designation}</span>
        {{else}}
        <span style="color:Blue;">${Designation}</span>
        {{/if}}            
        </td>
        <td>
        {{each(i,technology) TechnicalExpertise}}
            <div style="font-style:italic;border-width : 1px; border-style: dotted;">
            ${i + 1}. ${technology}
            </div>
        {{/each}}
        </td>
        <td>
            ${FormattedDate}
        </td>
    </tr>  
</script>

Replacement 2:

function jsonProjectMemberListSuccessCallback(data) {
    var targetElement = $('#memberData');

    targetElement.empty();
    
    for (var i in data) {
        var date = eval(data[i].JoiningDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
        var formattedDate = date.format("m/dd/yyyy");
        data[i].FormattedDate = formattedDate;
    }

    $("#memberDetailTemplate").tmpl(data).appendTo('#memberData');
}


Replacement 3:

<table border="0" cellpadding="0" cellspacing="5">
    <thead>
        <tr>
            <th>
                Member Name
            </th>
            <th>
                Experience
            </th>
            <th>
                Designation
            </th>
            <th>
                Technical Expertise
            </th>
            <th>
                Date of Joining
            </th>
        </tr>
    </thead>
    <tbody id="memberData">
    </tbody>
</table>


Now in the resultant you can see the respecitve columns related values.

ASP.NET MVC 3 and jQuery templates - Part1

In .Net and jQuery, templates are nothing but specification of a format/structure in which the associated data need to be represented. Developers who worked with ASP.NET controls like GiridView, ListView, Repeater... would have felt the power of templates already. To achieve the power of templates in client side jQuery templates comes in a handy form.

It is easy to understand the core idea on the implementation of jQuery templates with the snippet in this post. To understand the complete details on jQuery template please visit here. Now I'll provide snippet which helps you to understand how to use the jQuery templates.

Snippet 1(General html snippet describing the core jQuery template implementation)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>jQuery template core implementation</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
    <script id="memberDetailsTemplate" type="text/html">
            <tr>
                <td>
                    ${MemberName}
                </td>
                <td>
                    ${Designation}
                </td>
            </tr>

    </script>
    <script type="text/javascript">
        function applyTemplate() {
            var memberData = [
            { MemberName: "Member1", Designation: "Project Lead" },
            { MemberName: "Member2", Designation: "Tech Lead"}];

            $('#memberDetailsTemplate').tmpl(memberData).appendTo('#memberDetails');
        }

        $(document).ready(function () {
            applyTemplate();
        });
    </script>
</head>
<body>
    <table border="0" cellpadding="2" cellspacing="5">
        <thead>
            <tr style="font-weight:bold;">
                <td>
                    Member Name
                </td>
                <td>
                    Designation
                </td>
            </tr>
        </thead>
        <tbody id="memberDetails">
        </tbody>
    </table>
</body>
</html>


$('#memberDetailsTemplate').tmpl(memberData).appendTo('#memberDetails'); is the key statement that applies the template. Remaining are self explanatory. If the bound data is an array of object, then  the template will be repeated for each item in the array.

Three basic items required for applying jQuery template:
  1. template : Selector that specifies the template. $('#memberDetailsTemplate') in our case.
  2. data : Data to which the template need to be applied. memberData in our case.
  3. target : Selector that specifies the target element. ('#memberDetails') in our case.

.tmpl() is the method that help us achieving the template applied to the data. .appendTo() is one of the method that can be used in conjunction with the object(jQuery collection) returned from .tmpl().
So the statement specifies apply template $('#memberDetailsTemplate') over the data memberData and append the resultant to the ('#memberDetails').

Also, I've used the ${} template tag to read the value of the relevant property. Apart from this, there exists other template tags like {{if}}, {{else}}, {{each}}, {{html}}, {{tmpl}}, {{wrap}}. More details on those template tags can be got from http://api.jquery.com/category/plugins/templates/. We can also create named templates using .template() which you'll find helpful when using more number of templates frequently.

In this post, we just had an introduction for understanding the core idea behind jQuery templates. Part 2 focuses our topic of implementing the jQuery templates using ASP.NET MVC 3.

References
http://api.jquery.com/category/plugins/templates/

Saturday, August 6, 2011

Silverlight - Dependency property CLR wrapper setter/getter not executed

Several Silverlight developers raise this as issue when they first start implementing dependency properties in their custom controls in Silverlight. While developing custom controls when there is a need to expose a property that is target of some binding, animation ...., developers will end up in creating a dependency property of some specific type. For details on dependency properties, refer to the msdn documentation.

It is the CLR wrapper which is exposed in such a way that the values are get from or set to the dependency property identifier. The basic thumb rule for creating a dependency property is the hosting class should inherit from DependencyObject. DependencyObject is the one which stores and evaluates the value of dependency properties. DependencyObject exposes the GetValue() and SetValue() methods for storing and retrieving the values of related dependency properties. Hence the CLR wrappers will hold the GetValue() and SetValue() methods in their getter and setter respectively.

Any XAML binding expressions will be specified to the exposed CLR wrapper for binding values to the related dependency property. Ok, now think of a situation where we need to place some manipulation logic when the value of the dependency property is set or changes. When similar case arise for plain CLR properties, we'll obviously place the manipulation logic in the setter of the property. If we try to do the same in dependency property - CLR wrapper, we'll end up in the method not getting called as the CLR wrapper setter won't get executed. Actually the XAML processing engine is capable of interacting with the Silverlight property system directly and get or set the value of the related dependency property with the help of DependencyObject.

Hence if at all you want to have the logic executed when the value of dependency property changes, stuff it in the PropertyChangedCallback of the property metadata. Following is a brief sample on this.

Snippet: (Dependency property with PropertyChangedCallback)

public class MyCustomControl : Control
{
    public MyCustomControl()
    {
        this.DefaultStyleKey = typeof(MyCustomControl);
    }

    #region Dependency property with PropertyChangedCallback

    public string DisplayMessage
    {
        get
        {
            return (string)GetValue(DisplayMessageProperty);
        }
        set
        {
            SetValue(DisplayMessageProperty, value);

        }
    }

    public static readonly DependencyProperty DisplayMessageProperty =
        DependencyProperty.Register("DisplayMessage", typeof(string), typeof(MyCustomControl), new PropertyMetadata(string.Empty, OnDisplayMessageChanged));

    private static void OnDisplayMessageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Value change manipulation logic goes here......
    }

    #endregion
}


Placing additional logic in the CLR wrappers other than GetValue() and SetValue() should be avoided to eradicate any discrepancies.

References
http://msdn.microsoft.com/en-us/library/cc221408(v=vs.95).aspx
http://msdn.microsoft.com/en-us/library/cc903933(v=vs.95).aspx

Monday, August 1, 2011

Siverlight 4 - Using DependencyObjects or INotifyPropertyChanged as data objects / ViewModel

Making conviencing decision on representing data objects as whether to derive from DependencyObject or implement from INotifyPropertyChanged can sometimes become a daunting task. When implementing MVVM pattern this question arises while representing the ViewModel.
DependencyObject provides support for handling dependency properties. It is the dependency property which is capable of handling the data binding even through XAML (markup) extensions. There is no need for the manually notify the change in the property value, since the dependency property system automatically notifies the changes in the property.

Snippet 1 (Dependency property)

public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(ParameterMapControl), null);

public string Value
{
    get
    {
        return (String)GetValue(ValueProperty);
    }
    set
    {
        SetValue(ValueProperty, value);
    }
}



Snippet 2 (INotifyPropertyChanged)

public class SampleViewModel : INotifyPropertyChanged
{
    private string reportName;

    public string ReportName
    {
        get { return reportName; }
        set
        {
            reportName = value;
            NotifyPropertyChanged("ReportName");
        }
    }


    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion
}


Ok now think of in a different perspective, if the ViewModel is derived from the DependencyObject, exposed a dependency property and it is bind to the control in UI, any change in the property will notify the control. As an alternate we can implement the ViewModel from INotifyPropertyChanged which is usually represented as Plain Old CLR Objects (POCO) and manually provide the mechanism to notify the property changed.

The evaluation of property value, usage of resources (like memory) and the handling of binding sequence are well optimised to handle by the DependencyObject. Hence using DependencyObject to build data objects is not wrong. But we should also consider other factors.

Case 1
When we use INotifyPropertyChanged (POCO model) for data objects, in general the change notification code will be placed in the setter of the specific property. Also, the property change notification can be raised whenever required. This is especially helpful for read-only properties. While developing view model, several times we might be in a situation to specify a read-only property. For example, we can specify a read-only property which holds the functionality that represents a collection in sorted order and each and every time the original collection got changed, will trigger the change notification for the related read-only property.  But dealing this situation with DependencyObject is not pretty straightforward.

Case 2
Serialization of ViewModel will be your choice lot of time when you want to persist the state of the ViewModel for cases like reverting the object to a particular/previous state. Serialization mechanisms can be achieved over POCO easily where with DependencyObject,  we can't to do so.

Case 3
Passing as parameter to other services also favors POCO.

Case 4
Code readability, maintainability and flexibility are some of the main tenet of coding. DependencyObject lacks in these items when the ViewMode / data item goes a bit complex. Hence POCO is preferable here.

Summary
From the above, we can infer that implementing INotifyPropertyChanged for data items is handy in most of the cases. Dependency properties support great if it is the target of binding, animation, styles, template binding, etc, which will be very much helpful for us when we create custom controls.

Monday, July 25, 2011

Silverlight 4 - Getting value irrespective of the animation in progress

Gone are those days where animations in Silverlight are viewed as fancy add-ons. Nowadays simple animations are becoming an essential part of the Silverlight applications. Nothing much to imagine, displaying collection as list in brief generally and then displaying the same in detail upon selecting the list item is one such scenario where animation helps us a lot in achieving it. Ok, let us drift our focus to the topic now.

In such cases when animation in progress, there are times where we require to get the value of a property when no animation is applied. When I searched for such a mechanism, I came to know the availability of GetAnimationBaseValue method which takes a dependency property as parameter. As you might guess, since it takes any dependency property as parameter, the value is returned of type Object. It is our responsibility to cast the returned Object to the respective type.

Enough with description, let us feel it in code snippet as follows.

Snippet 1

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.Resources>
        <Storyboard x:Key="RectHeightStoryBoard" >
            <DoubleAnimation From="20" To="200" Duration="00:00:3" 
            Storyboard.TargetName="AnimationTestRectangle" 
            Storyboard.TargetProperty="Height"></DoubleAnimation>
        </Storyboard>
    </Grid.Resources>

    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>

    <Rectangle x:Name="AnimationTestRectangle" MouseLeftButtonDown="AnimationTestRectangle_MouseLeftButtonDown" 
               Fill="Crimson" Width="200" Height="20" Grid.ColumnSpan="2" />
    <StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Vertical">
        <StackPanel >
            <TextBlock Text="Height"  Margin="10"/>
            <TextBlock Name="HeightValueTextBlock" Text=""  Margin="10"/>
        </StackPanel>
        <StackPanel >
            <TextBlock Text="AnimationBaseValue Height"  Margin="10"/>
            <TextBlock Name="AnimationBaseValueTextBlock" Text=""  Margin="10"/>
        </StackPanel>
        
        <Button Content="Check Height" Name="CheckHeightButton" Width="85" Click="CheckHeightButton_Click" />
    </StackPanel>

</Grid>

Snippet 2

public partial class GetAnimationBaseValueTest : UserControl
{
    public GetAnimationBaseValueTest()
    {
        InitializeComponent();
        
    }

    private void AnimationTestRectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Storyboard rectHeightStoryBoard = (Storyboard)LayoutRoot.Resources["RectHeightStoryBoard"];
        rectHeightStoryBoard.Begin();

        ReadAnimationTestRectangleHeight();
    }

    private void CheckHeightButton_Click(object sender, RoutedEventArgs e)
    {
        ReadAnimationTestRectangleHeight();          
    }

    private void ReadAnimationTestRectangleHeight()
    {
        HeightValueTextBlock.Text = AnimationTestRectangle.Height.ToString();
        AnimationBaseValueTextBlock.Text = AnimationTestRectangle.GetAnimationBaseValue(HeightProperty).ToString();
    }
    
}


In the above snippet, I've created a storyboard targeting a rectangle for animating the height of the rectangle with some time delay. In the Click event of the CheckHeightButton, I'm calculating the height normally and then using the GetAnimationBaseValue method and displaying the values in related textblocks for verification. In the MouseLeftButtonDown event of the rectangle, I start the animation from the codebehind. Now, in order to evaluate, first click on the rectangle which triggers the animation. In due course when the animation in progress, click on the CheckHeightButton which displays the resultant values. There you can infer the use of GetAnimationBaseValue method.

Thursday, July 14, 2011

Silverlight 4 - Save UIElement as image in IsolatedStorage

One of the common feature expectation in Silverlight Application is the option to save the entire page or part of the page as image. There are pretty good articles over the web to save an UIElement as an image. One such article is posted by Victor Gaudioso here.

Our example is going to deal with saving an UIElement in Silverlight as png image in isolated storage. WriteableBitmap accepts UIElement which in turn need to be encoded for which I use Joe Stegman’s PngEncoder. Following code Snippet 1,
  • Generates the png stream with the help of PngEncoder
  • Creates the byte[] from the png stream
  • Checks for the available free space in the isolated storage and increase quota if needed
  • Save the image in png format in the isolated storage.
Snippet 1
private void SaveInIsolatedStorage()
{
    string fileName = "FileCheck1.png";
    Byte[] printBuffer;
    System.Windows.Media.Imaging.WriteableBitmap wBitmap;
    
    wBitmap = new WriteableBitmap(ElGrid, null);

    wBitmap.Invalidate();

    System.IO.Stream pngStream = Encode(wBitmap); 

    printBuffer = new Byte[pngStream.Length];
    pngStream.Read(printBuffer, 0, printBuffer.Length);
    
    if (!FileExists(fileName))
    {
        using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
        {
            if (isoStore.AvailableFreeSpace < pngStream.Length)
            {                        
                if (isoStore.IncreaseQuotaTo(isoStore.Quota + (pngStream.Length - isoStore.AvailableFreeSpace) + 1024))
                {
                    using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.CreateNew, isoStore))
                    {
                        stream.Write(printBuffer, 0, printBuffer.Length);
                    }
                }
            }
            else
            {
                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.CreateNew, isoStore))
                {
                    stream.Write(printBuffer, 0, printBuffer.Length);
                }
            }
            
        }

    }
    
}

Snippet 2
(Encode: got from an article. Download PngEncode.cs from the above specified blogs in order to execute the line "return PngEncoder.Encode(buffer, w, h);")
public static Stream Encode(WriteableBitmap wb)
{
    int w = wb.PixelWidth;
    int h = wb.PixelHeight;
    int adr;

    int rowLength = w * 4 + 1;

    byte[] buffer = new byte[rowLength * h];

    for (int y = 0; y < h; y++)
    {
        buffer[y * rowLength] = 0; // filter byte

        for (int x = 0; x < w; x++)
        {
            adr = y * rowLength + x * 4 + 3;

            int pixel = wb.Pixels[x + y * w];

            buffer[adr--] = (byte)(pixel & 0xff); pixel >>= 8;
            buffer[adr--] = (byte)(pixel & 0xff); pixel >>= 8;
            buffer[adr--] = (byte)(pixel & 0xff); pixel >>= 8;
            buffer[adr] = (byte)(pixel & 0xff);
        }
    }

    return PngEncoder.Encode(buffer, w, h);
}

In order to verify the storage manually, follow the path "C:\Users\[USER NAME]\AppData\LocalLow\Microsoft\Silverlight\is" in windows 7.

To save the image in the database, modify the Snippet 1 by removing the isolated storage related code (probably lines after 15) and make use of the printBuffer byte[] for storage.

This is just to introduce a basic idea of saving an UIElement in image format. Different encoders need to be used with respect to the format to be saved. Libraries like http://imagetools.codeplex.com/ can help you to achieve this.

References
http://blogs.msdn.com/b/jstegman/archive/2008/04/21/dynamic-image-generation-in-silverlight.aspx
http://www.windowspresentationfoundation.com/?p=406
http://imagetools.codeplex.com/
Creative Commons License
This work by Tito is licensed under a Creative Commons Attribution 3.0 Unported License.