Sunday, February 19, 2012

MVC Mask Attribute for Inputs

I created a mask input in previous posts where I declared Jquery as a constant and added it to Scripts collection. Alternate approach can be generate an Id for each mask input and use scripts in EditorTemplate.
MaskAttribute
  1. public void OnMetadataCreated(ModelMetadata metadata)
  2.         {
  3.             metadata.TemplateHint = "_maskInput";
  4.             metadata.AdditionalValues["id"] = Guid.NewGuid();
  5.             metadata.AdditionalValues["mask"] = Mask;
  6.         }
Register mask for input in document ready event.
Views\Shared\EditorTemplates\_maskInput.cshtml
  1. @using MvcLists.Common.CustomAttributes
  2. @model System.String
  3. @{
  4.     var additionalValues = ViewData.ModelMetadata.AdditionalValues;
  5.     var mask = additionalValues.SingleOrDefault(x=>x.Key=="mask").Value;
  6.     var id = additionalValues.SingleOrDefault(x => x.Key == "id").Value;
  7. }
  8. @{ var maskedInput = ViewData.GetModelAttribute<MaskAttribute>();
  9.    if (maskedInput != null)
  10.    {
  11.         <div class="editor-label">
  12.             @Html.LabelForModel()
  13.         </div>
  14.         <div class="editor-field">
  15.             @Html.TextBoxFor(m => m, new { id = @id })
  16.         </div>
  17.    }
  18. }
  19. <script type="text/javascript">
  20.     $(document).ready(function () {
  21.         $("#@id").mask('@mask');
  22.     });
  23. </script>

Saturday, February 18, 2012

MVC strip mask characters

In Previous post,I created masked inputs but on form post,it is posting mask characters as well. We can strip these characters using ModelBinders and thus can post numeric data only.
Common\ModelBinders\StripMaskCharacters.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text.RegularExpressions;
  5. using System.Web;
  6. using System.Web.Mvc;
  7. using MvcLists.Common.CustomAttributes;
  8.  
  9. namespace MvcLists.Common.ModelBinders
  10. {
  11.     public class StripMaskCharacters : DefaultModelBinder
  12.     {
  13.         protected override void SetProperty(ControllerContext controllerContext,
  14.                                             ModelBindingContext bindingContext,
  15.                                             System.ComponentModel.PropertyDescriptor propertyDescriptor,
  16.                                             object value)
  17.         {
  18.            if(value!=null && propertyDescriptor.PropertyType==(typeof(string)))
  19.            {
  20.                value = ((string) value).Trim();
  21.                if ((string)value == string.Empty)
  22.                {
  23.                    value = null;
  24.                }
  25.                else if(propertyDescriptor.Attributes[typeof(MaskAttribute)]!=null
  26.                    && bindingContext.ValueProvider.GetValue(propertyDescriptor.Name)!=null
  27.                    && bindingContext.ValueProvider.GetValue(propertyDescriptor.Name).AttemptedValue!=null)
  28.                {
  29.                    value = Regex.Replace(bindingContext.ValueProvider.GetValue(propertyDescriptor.Name).AttemptedValue,
  30.                                          "[^0-9]", string.Empty);
  31.                }
  32.            }
  33.             base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);
  34.         }
  35.     }
  36. }
Then register this model binder in Application_Start of global.asax
Global.asax
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using System.Web.Routing;
  7. using FluentValidation.Mvc;
  8. using MvcLists.Common.DataAnnotations;
  9. using MvcLists.Common.ModelBinders;
  10.  
  11. namespace MvcLists
  12. {
  13.     // Note: For instructions on enabling IIS6 or IIS7 classic mode,
  14.     // visit http://go.microsoft.com/?LinkId=9394801
  15.  
  16.     public class MvcApplication : System.Web.HttpApplication
  17.     {
  18.         public static void RegisterGlobalFilters(GlobalFilterCollection filters)
  19.         {
  20.             filters.Add(new HandleErrorAttribute());
  21.         }
  22.  
  23.         public static void RegisterRoutes(RouteCollection routes)
  24.         {
  25.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  26.  
  27.             routes.MapRoute(
  28.                 "Default", // Route name
  29.                 "{controller}/{action}/{id}", // URL with parameters
  30.                 new { controller = "Person", action = "Index", id = UrlParameter.Optional } // Parameter defaults
  31.             );
  32.  
  33.         }
  34.  
  35.         protected void Application_Start()
  36.         {
  37.             AreaRegistration.RegisterAllAreas();
  38.  
  39.             RegisterGlobalFilters(GlobalFilters.Filters);
  40.             RegisterRoutes(RouteTable.Routes);
  41.             ModelMetadataProviders.Current=new MyModelMetaDataProvider();
  42.             ModelBinders.Binders.DefaultBinder = new StripMaskCharacters();
  43.             FluentValidationModelValidatorProvider.Configure();
  44.         }
  45.         protected void Application_BeginRequest()
  46.         {
  47.             HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
  48.             HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
  49.             HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
  50.             HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
  51.             HttpContext.Current.Response.Cache.SetNoStore();
  52.  
  53.         }
  54.     }
  55. }

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;
            }
        }
    }
}