Saturday, February 18, 2012

MVC Masked Input

One can use jquery to mask the inputs.There are quiet a few good plugins available for this e.g. http://digitalbush.com/projects/masked-input-plugin/

Only drawback to this approach is we need to link jquery function for each input to be masked.
Alternate approach can be creating a data annotation for mask and use it on model/viwModel.

Step 1: Create a mask attribute
Common\CustomAttributes\MaskAttribute.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6.  
  7. namespace MvcLists.Common.CustomAttributes
  8. {
  9.     [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
  10.     public class MaskAttribute:Attribute,IMetadataAware
  11.     {
  12.         private string _mask = string.Empty;
  13.         public MaskAttribute(string mask)
  14.         {
  15.             _mask = mask;
  16.         }
  17.  
  18.         public string Mask
  19.         {
  20.             get { return _mask; }
  21.         }
  22.  
  23.         private const string ScriptText = "<script type='text/javascript'>" +
  24.                                            "$(document).ready(function () {{" +
  25.                                            "$('#{0}').mask('{1}');}});</script>";
  26.  
  27.         public const string templateHint = "_maskedInput";
  28.  
  29.         private int _count;
  30.  
  31.         public string Id
  32.         {
  33.             get { return "maskedInput_" + _count; }
  34.         }
  35.  
  36.         internal HttpContextBase Context
  37.         {
  38.             get { return new HttpContextWrapper(HttpContext.Current); }
  39.         }
  40.  
  41.         public void OnMetadataCreated(ModelMetadata metadata)
  42.         {
  43.             var list = Context.Items["Scripts"] as IList<string> ?? new List<string>();
  44.             _count = list.Count;
  45.             metadata.TemplateHint = templateHint;
  46.             metadata.AdditionalValues[templateHint] = Id;
  47.             list.Add(string.Format(ScriptText, Id, Mask));
  48.             Context.Items["Scripts"] = list;
  49.         }
  50.     }
  51. }
Step 2:Create a partial view in EditorTemplates and add an extension method for ViewDataDictionary to get the attribute for the property
Views\Shared\EditorTemplates\_mask.cshtml
  1. @using MvcLists.Common.CustomAttributes
  2. @model System.String
  3. @{ var maskedInput = ViewData.GetModelAttribute<MaskAttribute>();
  4.    if (maskedInput != null)
  5.    {
  6.         <div class="editor-label">
  7.             @Html.LabelForModel()
  8.         </div>
  9.         <div class="editor-field">
  10.             @Html.TextBoxFor(m => m, new { id = ViewData.ModelMetadata.AdditionalValues[MaskAttribute.templateHint] })
  11.         </div>
  12.    }
  13. }
Common\MvcExtensions\ViewDataExtensions.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6.  
  7. namespace MvcLists.Common.MvcExtensions
  8. {
  9.     public static class ViewDataExtensions
  10.     {
  11.         public static TAttribute GetModelAttribute<TAttribute>(this ViewDataDictionary viewData,bool inherit=false) where TAttribute:Attribute
  12.         {
  13.             if(viewData==null) throw new ArgumentException("ViewData");
  14.             var containerType = viewData.ModelMetadata.ContainerType;
  15.             return
  16.                 ((TAttribute[])
  17.                  containerType.GetProperty(viewData.ModelMetadata.PropertyName).GetCustomAttributes(typeof (TAttribute),
  18.                                                                                                     inherit)).
  19.                     FirstOrDefault();
  20.                     
  21.         }
  22.     }
  23. }
Common\HtmlHelpers\HtmlHelpers.cs
  1. public static IHtmlString RenderScripts(this HtmlHelper htmlHelper)
  2.         {
  3.             var scripts = htmlHelper.ViewContext.HttpContext.Items["Scripts"] as IList<string>;
  4.             if (scripts != null)
  5.             {
  6.                 var builder = new StringBuilder();
  7.                 foreach (var script in scripts)
  8.                 {
  9.                     builder.AppendLine(script);
  10.                 }
  11.                 return new MvcHtmlString(builder.ToString());
  12.             }
  13.             return null;
  14.         }
Step 3: Register this new extension in web.config of Views folder.
Web.config
  1.  
  2.   < system.web.webPages.razor >
  3.     < host factoryType= "System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  4.     < pages pageBaseType= "System.Web.Mvc.WebViewPage" >
  5.       < namespaces >
  6.         < add namespace= "System.Web.Mvc" />
  7.         < add namespace= "System.Web.Mvc.Ajax" />
  8.         < add namespace= "System.Web.Mvc.Html" />
  9.         < add namespace= "System.Web.Routing" />
  10.         < add namespace= "MvcLists.Common.MvcExtensions" />
  11.       </ namespaces >
  12.     </ pages >
  13.   </ system.web.webPages.razor >
Step 4: Use this attribute on Model/ViewModels property.
Models\Person.cs
  1. public class Person
  2.     {
  3.         [Tooltip("Enter First Name")]
  4.         public string FirstName { get; set; }
  5.         [Tooltip("Enter Last Name")]
  6.         public string LastName { get; set; }
  7.         [Tooltip("Enter SSN")]
  8.         [Mask("999-99-9999")]
  9.         public string SSN { get; set; }
  10.         [Tooltip("Enter Age")]
  11.         [Mask("99")]
  12.         public string Age { get; set; }
  13.         [Mask("999-999-9999")]
  14.         [Tooltip("Enter Phone")]
  15.         public string Phone { get; set; }
  16.         [Mask("99999-9999")]
  17.         [Tooltip("Enter Zip Code")]
  18.         public string ZipCode { get; set; }
  19.         [Mask("9999-9999-9999-9999")]
  20.         [Tooltip("Enter Credit Card")]
  21.         public string CreaditCard { get; set; }
  22.  
  23.     }
Step 5: Render the UI.
Views\Person\Index.cshtml
  1. @using (Html.BeginForm("Index","Person"))
  2. {
  3.     @Html.ValidationSummary(true)
  4.     <fieldset>
  5.         <legend>Person</legend>
  6.         <div class="editor-label">
  7.             @Html.LabelFor(model => model.FirstName)
  8.         </div>
  9.         <div class="editor-field">
  10.             @Html.TextBoxFor(model => model.FirstName,new{title=@Html.TooltipFor(x=>x.FirstName)})
  11.             @Html.ValidationMessageFor(model => model.FirstName)
  12.         </div>
  13.         <div class="editor-label">
  14.             @Html.LabelFor(model => model.LastName)
  15.         </div>
  16.         <div class="editor-field">
  17.             @Html.TextBoxFor(model => model.LastName,new{title=Html.TooltipFor(x=>x.LastName)})
  18.             @Html.ValidationMessageFor(model => model.LastName)
  19.         </div>
  20.         @Html.EditorFor(x => x.SSN)
  21.         @Html.EditorFor(x => x.Age)
  22.         @Html.EditorFor(x => x.Phone)
  23.         @Html.EditorFor(x => x.CreaditCard)
  24.         @Html.EditorFor(x => x.ZipCode)
  25.         <p>
  26.             <input type="submit" value="Create" />
  27.         </p>
  28.     </fieldset>
  29. }
Output:

Monday, February 13, 2012

Refresh scripts and CSS in browser after deployment

To refresh browser cache after deployment,one can append the assembly hashcode to the script's url so that scripts and CSS will be fetched from server instead of cache.


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using System.Reflection;
  7. using System.Text;
  8.  
  9. namespace MvcCommon.Common
  10. {
  11.     public static class HtmlHelpers
  12.     {
  13.         private static int HashCode
  14.         {
  15.             get { return Assembly.GetCallingAssembly().GetHashCode(); }
  16.         }
  17.         private static UrlHelper UrlHelper(HtmlHelper htmlHelper)
  18.         {
  19.             return new UrlHelper(htmlHelper.ViewContext.RequestContext);
  20.         }
  21.         public static HtmlString IncludeCSS(this HtmlHelper htmlHelper, params string[] urls)
  22.         {
  23.             var scripts = new StringBuilder();
  24.             
  25.             urls.ToList().ForEach(x=>{
  26.                 var href=UrlHelper(htmlHelper).Content(string.Format("~/Content/{0}",x))+"?"+HashCode;
  27.                 var script = string.Format("<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />", href);
  28.                 scripts.AppendLine(script);
  29.             });
  30.  
  31.             return new HtmlString(scripts.ToString());
  32.         }
  33.         public static HtmlString IncludeJQueries(this HtmlHelper htmlHelper, params string[] urls)
  34.         {
  35.             var scripts = new StringBuilder();
  36.             
  37.             urls.ToList().ForEach(x=>{
  38.                 var href=UrlHelper(htmlHelper).Content(string.Format("~/Scripts/{0}",x))+"?"+HashCode;
  39.                 var script=string.Format("<script src=\"{0}\" type=\"text/javascript\"></script>",href);
  40.                 scripts.AppendLine(script);
  41.             });
  42.  
  43.             return new HtmlString(scripts.ToString());
  44.         }
  45.     }
  46. }

Thursday, January 26, 2012

WCF hosting in WAS

Step 1: Add a service library and a service host.
Step 2: Add tcpBinding and mexTcpBinding.
Step 3: Enable net.tcp protocol for the deployed service in Advanced Settings
section.
Step 4: Browse the svc and test the address for tcpBinding using WCFTestClient
(getting error with WcfStorm for tcp)

Step 2:

Code Snippet
  1. <?xml version="1.0"?>
  2. <configuration>
  3.  
  4.   <system.web>
  5.     <compilation debug="true" targetFramework="4.0" />
  6.   </system.web>
  7.   <system.serviceModel>
  8.     <services>
  9.       <service name="ConfirmWCFTCP.Service1" behaviorConfiguration="MyServicebehavior">
  10.         <endpoint address="" binding="netTcpBinding" contract="ConfirmWCFTCP.IService1"/>
  11.         <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
  12.       </service>
  13.     </services>
  14.     
  15.     <behaviors>
  16.       <serviceBehaviors>
  17.         <behavior name="MyServicebehavior">
  18.           <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
  19.           <serviceMetadata httpGetEnabled="true"/>
  20.           <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
  21.           <serviceDebug includeExceptionDetailInFaults="false"/>
  22.         </behavior>
  23.       </serviceBehaviors>
  24.     </behaviors>
  25.     <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  26.   </system.serviceModel>
  27.   <system.webServer>
  28.     <modules runAllManagedModulesForAllRequests="true"/>
  29.   </system.webServer>
  30.  
  31. </configuration>

Step 3:

Wednesday, December 15, 2010

Using Conventions in NHibernate

Case: When your DB tanle name conventions and C# class name conventions are different,then to create map between these two, we can create conventions.

Step 1: Create a domain level attribute to define DB table for each C# class we need to map.

public class MyAttribute :Attribute
{
       public MyAttribute(string tableName)
       {
             TableName=tableName;
        }
       public string TableName{get;set;}

}

step 2: Declare TableName attribute on domain object
[MyAttribute("Employee_Details")]
public class Employee
{
      public virtual string Name{get;set;}
      public virtual long SSN{get;set;}
}

step3: Create convention

public class TableNameConvention : IClassConvention
step 4: Hook convention to NH configuration

var configuration=AutoMap.AssemblyOf<Employee>()
                           .conventions.Add(typeof(TableNameConvention))
{
    public void Apply(IClassInstance instance)
    {
         instance.table(SetTableName(instance));
    }
    private string SetTableName(IClassInstance instance)
    {
       var attributes = instance.EntityType.GetCustomAttributes(false);
       foreach(var attribute in attributes)
       {
          if(attribute is MyAttribute)
          {
             return ((MyAttribute)attribute).TableName;

}
           }
        return instance.EntityType.Name;

}
}
}

Wednesday, March 31, 2010

WPF TreeView with Custom Object Collections


XAML:


<Window x:Class="MyTreeView.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:my="clr-namespace:MyTreeView"  
    Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
    <Grid Width="281">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <Grid.Resources>
            <my:ListLeague x:Key="MyList"/>

            <HierarchicalDataTemplate DataType    = "{x:Type my:League}"
                                ItemsSource = "{Binding Path=Divisions}">
                <TextBlock Text="{Binding Path=LeagueName}"/>
            </HierarchicalDataTemplate>

            <HierarchicalDataTemplate DataType= "{x:Type my:Division}"
                                ItemsSource = "{Binding Path=Teams}">
                <TextBlock Text="{Binding Path=DivisionName}"/>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType= "{x:Type my:Team}"
                                ItemsSource = "{Binding Path=Players}">
                <TextBlock Text="{Binding Path=TeamName}"/>
            </HierarchicalDataTemplate>

            <!--<DataTemplate DataType="{x:Type my:Player}">
                <TextBlock Text="{Binding Path=FName}"/>
            </DataTemplate>-->
        </Grid.Resources>
        <TreeView x:Name="tvLeague" Grid.Row="0" SelectedItemChanged="tvLeague_SelectedItemChanged">
           <!-- <TreeViewItem ItemsSource="{Binding Source={StaticResource MyList}}" Header="My Soccer Leagues" />-->
        </TreeView>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button Width="80" Height="30" Click="Button_Click" Content="Add Zone" />
            <Button Width="80" Height="30" Click="Button_Click_1" Content="Add Team"/>
          
        </StackPanel>

    </Grid>
</Window>

Code :



using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Collections.ObjectModel;
namespace MyTreeView
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private ObservableCollection<League> lstLeague = new ObservableCollection<League>();
        public League CurrentLeague { get; set; }
        public Division CurrentDivision { get; set; }
        public Team CurrentTeam { get; set; }
        private int j = 0;
        public Window1()
        {
            InitializeComponent();
        }


        private void Button_Click(object sender, RoutedEventArgs e)
        {
            lstLeague.ToList().Find(i => i.LeagueName == CurrentLeague.LeagueName).
                Divisions.Add(new Division { DivisionName = string.Format("New Zone {0}", j++), Teams = new ObservableCollection<Team>() });
           
        }
        private void tvLeague_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (((TreeView)sender).SelectedItem.GetType().Equals(typeof(League)))
            {
                League league = ((TreeView)sender).SelectedItem as League;
                CurrentLeague = league;
                
            }
            else if (((TreeView)sender).SelectedItem.GetType().Equals(typeof(Division)))
            {
                Division division = ((TreeView)sender).SelectedItem as Division;
                CurrentDivision = division;
               
            }
            else if (((TreeView)sender).SelectedItem.GetType().Equals(typeof(Team)))
            {
                Team team = ((TreeView)sender).SelectedItem as Team;
                CurrentTeam = team;


            }


        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            League l;
            Division d;
            Division d1; Division d2; Division d3; Team t1; Team t2; Team t3; Team t4;
            Player p1; Player p2; Player p3; Player p4;


            lstLeague.Add(l = new League { LeagueName = "IPL", Divisions = new ObservableCollection<Division>() });




            d = new Division { DivisionName = "EAST", Teams = new ObservableCollection<Team>() };
            d1 = new Division { DivisionName = "WEST", Teams = new ObservableCollection<Team>() };
            d2 = new Division { DivisionName = "SOUTH", Teams = new ObservableCollection<Team>() };
            d3 = new Division { DivisionName = "NORTH", Teams = new ObservableCollection<Team>() };


            l.Divisions.Add(d1);
            l.Divisions.Add(d2);
            l.Divisions.Add(d3);
            l.Divisions.Add(d);


            t1 = new Team { TeamName = "MI", Players = new ObservableCollection<Player>() };
            t2 = new Team { TeamName = "KKR", Players = new ObservableCollection<Player>() };
            t3 = new Team { TeamName = "RR", Players = new ObservableCollection<Player>() };
            t4 = new Team { TeamName = "CS", Players = new ObservableCollection<Player>() };


            d.Teams.Add(t1);
            d1.Teams.Add(t2);
            d2.Teams.Add(t3);
            d3.Teams.Add(t4);
            p1 = new Player { FName = "P1", LName = "p1" };
            p2 = new Player { FName = "P1", LName = "p1" };
            p3 = new Player { FName = "P1", LName = "p1" };
            p4 = new Player { FName = "P1", LName = "p1" };


            t1.Players.Add(p1);
            t2.Players.Add(p2);
            t3.Players.Add(p3);
            t4.Players.Add(p4);


            lstLeague.Add(l = new League { LeagueName = "ICL", Divisions = new ObservableCollection<Division>() });




            d = new Division { DivisionName = "EAST", Teams = new ObservableCollection<Team>() };
            d1 = new Division { DivisionName = "WEST", Teams = new ObservableCollection<Team>() };
            d2 = new Division { DivisionName = "SOUTH", Teams = new ObservableCollection<Team>() };
            d3 = new Division { DivisionName = "NORTH", Teams = new ObservableCollection<Team>() };


            l.Divisions.Add(d1);
            l.Divisions.Add(d2);
            l.Divisions.Add(d3);
            l.Divisions.Add(d);


            t1 = new Team { TeamName = "MI", Players = new ObservableCollection<Player>() };
            t2 = new Team { TeamName = "KKR", Players = new ObservableCollection<Player>() };
            t3 = new Team { TeamName = "RR", Players = new ObservableCollection<Player>() };
            t4 = new Team { TeamName = "CS", Players = new ObservableCollection<Player>() };


            d.Teams.Add(t1);
            d1.Teams.Add(t2);
            d2.Teams.Add(t3);
            d3.Teams.Add(t4);
            p1 = new Player { FName = "P1", LName = "p1" };
            p2 = new Player { FName = "P1", LName = "p1" };
            p3 = new Player { FName = "P1", LName = "p1" };
            p4 = new Player { FName = "P1", LName = "p1" };


            t1.Players.Add(p1);
            t2.Players.Add(p2);
            t3.Players.Add(p3);
            t4.Players.Add(p4);
            tvLeague.ItemsSource = lstLeague;
        }


        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            lstLeague.ToList().Find(i=>i.LeagueName==CurrentLeague.LeagueName).Divisions.ToList().Find(i=>i.DivisionName==CurrentDivision.DivisionName).
                Teams.Add(new Team{TeamName=string.Format("New Team {0}",j++),Players=new ObservableCollection<Player>()});
        }


        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
           
        }


        


        
    }
    public class League 
    {
        public League()
        {
           
        }
        public string LeagueName { get; set; }
        public ObservableCollection<Division> Divisions { get; set; }
    }
    public class Division
    {
        public Division()
        {
            
        }
        public string DivisionName { get; set; }
        public ObservableCollection<Team> Teams { get; set; }
    }
    public class Team
    {
        public Team() { }
        public string TeamName { get; set; }
        public ObservableCollection<Player> Players { get; set; } 
    }
    public class Player
    {
        public Player() { }
        public string FName { get; set; }
        public string LName { get; set; }
    }
    public class ListLeague : ObservableCollection<League>
    {
        public ListLeague()
        {
            League l;
            Division d;
            Division d1; Division d2; Division d3; Team t1; Team t2; Team t3; Team t4;
            Player p1; Player p2; Player p3; Player p4;
            
             Add(l = new League { LeagueName = "IPL" ,Divisions=new ObservableCollection<Division>()});
            


            d = new Division { DivisionName = "EAST" ,Teams=new ObservableCollection<Team>()};
            d1 = new Division { DivisionName = "WEST", Teams = new ObservableCollection<Team>() };
            d2 = new Division { DivisionName = "SOUTH", Teams = new ObservableCollection<Team>() };
            d3 = new Division { DivisionName = "NORTH", Teams = new ObservableCollection<Team>() };


            l.Divisions.Add(d1);
            l.Divisions.Add(d2);
            l.Divisions.Add(d3);
            l.Divisions.Add(d);


            t1 = new Team { TeamName = "MI",Players=new ObservableCollection<Player>() };
            t2 = new Team { TeamName = "KKR", Players = new ObservableCollection<Player>() };
            t3 = new Team { TeamName = "RR", Players = new ObservableCollection<Player>() };
            t4 = new Team { TeamName = "CS", Players = new ObservableCollection<Player>() };


            d.Teams.Add(t1);
            d1.Teams.Add(t2);
            d2.Teams.Add(t3);
            d3.Teams.Add(t4);
            p1 = new Player { FName = "P1", LName = "p1" };
            p2 = new Player { FName = "P1", LName = "p1" };
            p3 = new Player { FName = "P1", LName = "p1" };
            p4 = new Player { FName = "P1", LName = "p1" };


            t1.Players.Add(p1);
            t2.Players.Add(p2);
            t3.Players.Add(p3);
            t4.Players.Add(p4);


            Add(l = new League { LeagueName = "ICL", Divisions = new ObservableCollection<Division>() });




            d = new Division { DivisionName = "EAST", Teams = new ObservableCollection<Team>() };
            d1 = new Division { DivisionName = "WEST", Teams = new ObservableCollection<Team>() };
            d2 = new Division { DivisionName = "SOUTH", Teams = new ObservableCollection<Team>() };
            d3 = new Division { DivisionName = "NORTH", Teams = new ObservableCollection<Team>() };


            l.Divisions.Add(d1);
            l.Divisions.Add(d2);
            l.Divisions.Add(d3);
            l.Divisions.Add(d);


            t1 = new Team { TeamName = "MI", Players = new ObservableCollection<Player>() };
            t2 = new Team { TeamName = "KKR", Players = new ObservableCollection<Player>() };
            t3 = new Team { TeamName = "RR", Players = new ObservableCollection<Player>() };
            t4 = new Team { TeamName = "CS", Players = new ObservableCollection<Player>() };


            d.Teams.Add(t1);
            d1.Teams.Add(t2);
            d2.Teams.Add(t3);
            d3.Teams.Add(t4);
            p1 = new Player { FName = "P1", LName = "p1" };
            p2 = new Player { FName = "P1", LName = "p1" };
            p3 = new Player { FName = "P1", LName = "p1" };
            p4 = new Player { FName = "P1", LName = "p1" };


            t1.Players.Add(p1);
            t2.Players.Add(p2);
            t3.Players.Add(p3);
            t4.Players.Add(p4);
            
            
        }
        public League this[string name]
        {
            get
            {
                foreach (League l in this)
                    if (l.LeagueName == name)
                        return l;


                return null;
            }
        }
    }
}







Thursday, March 25, 2010

WPF TreeView

XAML


<Window x:Class="WpfApplication3.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:data="clr-namespace:WpfApplication3"  
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <HierarchicalDataTemplate DataType="{x:Type data:Root}" ItemsSource="{Binding Path=WebPages}">
        <StackPanel>
            <TextBlock Text="{Binding Path=Title}"></TextBlock>
        </StackPanel>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate DataType="{x:Type data:WebPage}" ItemsSource="{Binding Path=LinksInPage}"  >
            <TextBlock Text="{Binding Path=PageTitle}"></TextBlock>
    </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
        <TreeView Margin="0,0,15,0" Name="treeView1" Background="LightSkyBlue">
            <TreeViewItem ItemsSource="{Binding Path=WebPages}"
                          Header="{Binding Title}"></TreeViewItem>
        </TreeView>
    </Grid>
</Window>

Code Behind


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication3
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            Root r = new Root();
            r.WebPages = new List<WebPage>();
            r.Title = "HomePage";
            r.Url = @"http://www.HomePage.com";

            WebPage link1 = new WebPage();
            link1.Href = @"http://www.HomePage.com/link1";
            link1.PageTitle = "link1";
            r.WebPages.Add(link1);

            WebPage Link2 = new WebPage();
            Link2.Href = @"http://www.HomePage.com/Link2";
            Link2.PageTitle = "Link2";
            r.WebPages.Add(Link2);

            WebPage Link3 = new WebPage();
            Link3.Href = @"http://www.HomePage.com/Link2/Link3";
            Link3.PageTitle = "Link3";
            Link2.LinksInPage = new List<WebPage>();
            Link2.LinksInPage.Add(Link3);

            WebPage Link4 = new WebPage();
            Link4.Href = @"http://www.HomePage.com/Link2/Link4";
            Link4.PageTitle = "Link4";
            Link2.LinksInPage.Add(Link4);

            WebPage Link5 = new WebPage();
            Link5.Href = @"http://www.HomePage.com/link1/Link5";
            Link5.PageTitle = "Link5";
            link1.LinksInPage = new List<WebPage>();
            link1.LinksInPage.Add(Link5);

            WebPage Link6 = new WebPage();
            Link6.Href = @"http://www.HomePage.com/link2/Link3/Link6";
            Link6.PageTitle = "Link6";
            Link3.LinksInPage = new List<WebPage>();
            Link3.LinksInPage.Add(Link6);

            treeView1.DataContext = r;
        
        }
    }
    public class WebPage
    {
        public string Href { get; set; }
        public string PageTitle { get; set; }
        public List<WebPage> LinksInPage { get; set; }
    }

    public class Root
    {
        public string Title { get; set; }
        public string Url { get; set; }
        public List<WebPage> WebPages { get; set; }
    }
}

Wednesday, March 24, 2010

WPF DataGrid Binding With Enum and Child Collection

<Window x:Class="SOTC_DataGridExample.Window1" Name="This"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
   xmlns:sys="clr-namespace:System;assembly=mscorlib"  
   xmlns:local="clr-namespace:SOTC_DataGridExample" 
   Title="DataGrid Example" Height="300" Width="500">
    <Window.Resources>
        <ObjectDataProvider x:Key="myEnum" ObjectType="{x:Type sys:Enum}" MethodName="GetValues">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:GenderType"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        <ObjectDataProvider x:Key="myContinentEnum" ObjectType="{x:Type sys:Enum}" MethodName="GetValues">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:Continent"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
    <Grid x:Name="dgRoot" DataContext="{Binding}">
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <dg:DataGrid x:Name="myGrid" ItemsSource="{Binding}" Grid.Row="0" Grid.Column="0" IsSynchronizedWithCurrentItem="True"
              Margin="5" AutoGenerateColumns="False" Width="365">
            <dg:DataGrid.Columns>
                <dg:DataGridTextColumn Binding="{Binding GameName}" Header="Game Name" />
                <dg:DataGridTextColumn Binding="{Binding Creator}" Header="Creator" />
                <dg:DataGridComboBoxColumn Header="Gender" ItemsSource="{Binding Source={StaticResource myEnum}}"
                                SelectedItemBinding="{Binding Gender}" />
                <dg:DataGridComboBoxColumn Header="Publisher" x:Name="_PublisherCombo"
                                SelectedItemBinding="{Binding Publisher}" />
                <dg:DataGridCheckBoxColumn Binding="{Binding OnXbox}" 
                                Header="On Xbox 360" />
                
            </dg:DataGrid.Columns>
        </dg:DataGrid>
        <dg:DataGrid x:Name="CountryGrid" Grid.Row="1" Grid.Column="0" IsSynchronizedWithCurrentItem="True"
                     ItemsSource="{Binding Path=CurrentItem.CityInfo}" AutoGenerateColumns="False" Width="195">
            <dg:DataGrid.Columns>
                <dg:DataGridTextColumn Binding="{Binding City}" Header="City" />
                <dg:DataGridTextColumn Binding="{Binding Country}" Header="Country" />
                <dg:DataGridComboBoxColumn Header="Continent" ItemsSource="{Binding Source={StaticResource myContinentEnum}}"
                                SelectedItemBinding="{Binding CountryIn}" />
                
            </dg:DataGrid.Columns>
        </dg:DataGrid>
    </Grid>
</Window>
Code Behind:

using System;
using System.Collections.Generic;
using System.Data;
using System.Windows;
using System.Collections.ObjectModel;

namespace SOTC_DataGridExample
{
    public enum GenderType { Male, Female };
    public enum Continent{NorthAmerica,Asia,Europe,Australia};

    public partial class Window1 : Window
    {
        private DataTable _GameData;

        public Window1()
        {
            List<GameData> _GameData = new List<GameData>();
            List<CityInfo> _cityInfo = new List<CityInfo>();
            _cityInfo.Add(new CityInfo() { City = "Mumbai", Country = "India", CountryIn = Continent.Asia });
            _cityInfo.Add(new CityInfo() { City = "London", Country = "UK", CountryIn = Continent.Europe });
            _cityInfo.Add(new CityInfo() { City = "Atlanta", Country = "USA", CountryIn = Continent.NorthAmerica });
            _cityInfo.Add(new CityInfo() { City = "Sydney", Country = "Australia", CountryIn = Continent.Australia });

            List<CityInfo> _cityInfo1 = new List<CityInfo>();
            _cityInfo1.Add(new CityInfo() { City = "Delhi", Country = "India", CountryIn = Continent.Asia });
            _cityInfo1.Add(new CityInfo() { City = "Leeds", Country = "UK", CountryIn = Continent.Europe });
            _cityInfo1.Add(new CityInfo() { City = "New York", Country = "USA", CountryIn = Continent.NorthAmerica });
            _cityInfo1.Add(new CityInfo() { City = "Melbourne", Country = "Australia", CountryIn = Continent.Australia });

            GameData gamedata;
            _GameData.Add(new GameData() {CityInfo=_cityInfo,GameName = "World Of Warcraft", Creator = "Blizzard", Publisher = "Blizzard", OnXbox = false, Gender = GenderType.Male });
            _GameData.Add(new GameData() { CityInfo = _cityInfo1, GameName = "Halo 3", Creator = "Bungie", Publisher = "Microsoft", OnXbox = true, Gender = GenderType.Female });
            _GameData.Add(new GameData() {CityInfo=_cityInfo, GameName = "Gears Of War", Creator = "Epic", Publisher = "Microsoft", OnXbox = true, Gender = GenderType.Male });
            _GameData.Add(new GameData() {CityInfo=_cityInfo, GameName = "World Of Warcraft", Creator = "Blizzard", Publisher = "Blizzard", OnXbox = false, Gender = GenderType.Male });

            /*_GameData = new DataTable();
            _GameData.Columns.Add(new DataColumn("Game Name", typeof(string)));
            _GameData.Columns.Add(new DataColumn("Creator", typeof(string)));
            _GameData.Columns.Add(new DataColumn("Publisher", typeof(string)));
            _GameData.Columns.Add(new DataColumn("On Xbox", typeof(bool)));
            _GameData.Columns.Add(new DataColumn("Gender", typeof(GenderType)));
            
            var row = _GameData.NewRow();
            _GameData.Rows.Add(row);
            row["Game Name"] = "World Of Warcraft";
            row["Creator"] = "Blizzard";
            row["Publisher"] = "Blizzard";
            row["On Xbox"] = false;
            row["Gender"] = GenderType.Male;
            row = _GameData.NewRow();
            _GameData.Rows.Add(row);
            row["Game Name"] = "Halo 3";
            row["Creator"] = "Bungie";
            row["Publisher"] = "Microsoft";
            row["On Xbox"] = true;
            row["Gender"] = GenderType.Female;
            row = _GameData.NewRow();
            _GameData.Rows.Add(row);
            row["Game Name"] = "Gears Of War";
            row["Creator"] = "Epic";
            row["Publisher"] = "Microsoft";
            row["On Xbox"] = true;
            row["Gender"] = GenderType.Male;
            _GameData.RowChanged += GameDataRowChanged;
            _GameData.RowDeleted += GameDataRowChanged;*/

            InitializeComponent();

            _PublisherCombo.ItemsSource = new List<string>() { "Activision", "Ubisoft",
                    "Microsoft", "Blizzard", "Nintendo", "Electronic Arts", 
                    "Take-Two Interactive" };
            dgRoot.DataContext = _GameData;
            //myGrid.DataContext = _GameData;
            //ItemsSource="{Binding ElementName=This, Path=GameData}" 
        }

        private void GameDataRowChanged(object sender, DataRowChangeEventArgs e)
        {
            Console.WriteLine("----Row Changed----");
            Console.WriteLine("Action: " + e.Action);
            if (e.Action != DataRowAction.Delete)
            {
                Console.Write("Values: ");
                foreach (var val in e.Row.ItemArray)
                { Console.Write(val + ", "); }
                Console.WriteLine();
            }
            Console.WriteLine("-------------------");
        }

        public DataTable GameData
        { get { return _GameData; } }
        
    }
    public class GameData
    { 
         public string GameName{get;set;}
        public string Creator{get;set;}
        public string Publisher{get;set;}
        public bool OnXbox{get;set;}
        public GenderType Gender{get;set;}
        public List<CityInfo> CityInfo { get; set; }
          
    }
    public class CityInfo
    {
        public string Country { get; set; }
        public string City { get; set; }
        public Continent CountryIn { get; set; }
    }
  
    

}