Friday, August 31, 2012

Visual Studio 2012 got rid of all unnecessary things!

I must say that I am not that much excited with the release of Visual Studio 2012, as I must learn everything from scratch again, in fact need to figure out what has changed since 2010. Once again I must confess that I liked vs 2010 more than vs 2012, let see where it goes as I would be exploring visual studio in coming weeks.

image

Only required project are in the window now Open-mouthed smile. No more lots of project template, but still we have one very interesting option now we can directly use online templates.

image

Man! why is this black and white crappy look, may be because of performance, once again I like vs 2010 more. I will create a web application now and see what is the difference.

Did anyone noticed we have still the web site creation feature in vs2012.

image 

Believe it or not web site template is not more improved and equipped with lot of modern technologies, I kind of sounds stupid but my feeling is funny and I can not express properly. Hope this will rock the world of Microsoft based technology developers.

Cheers!.

Friday, August 24, 2012

Thursday, August 16, 2012

How to manipulating master page controls in asp.net, when output caching is enabled?

Introduction

In this short article we are going to see how we can use some smart tricks for manipulating controls in master page of asp.net, from a content page. The topic seems a little bit lame and should be pretty strait forward but I wouldn’t be discussing with the community unless it has a very unexpected turn.

image

Here is the situation, we have a asp.net 4.0 web application with a single master page. In some cases we need to hide master page’s controls, in particular header and footer.

image

To demonstrate the ideas and story I have created a simple asp.net 4.0 web application in visual studio, the solution explorer components is given above as screen shot, nothing special just taken after creating the project.

“Site.Master” the site layout html is given bellow:

<body>
<form runat="server">
<div class="page">
<uc1:Header ID="Header1" runat="server" />
<div class="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
<div class="clear">
</div>
</div>
<uc2:Footer ID="Footer1" runat="server" />
</form>
</body>

Looks pretty innocent right, infect most of our web site template has header,main-content,footer generic style. Now then the requirement is to hide the header and footer in one of the content page, in fact in couple of pages, why those page are some kind of report page and its not necessary to show header and footer as those page can be printed.


Most easy way out


Most easy way out is just use find control method in page.master object and then simply hide them. we can also cast them to custom control and then set properties, this will work in 99% case and really simple. This can be found in net with one google only, and in first result will do the job. Bellow the code is given of the strait forward way.


public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var masterPage = Master;
if (masterPage != null)
{
masterPage.FindControl("Header1").Visible = false;
masterPage.FindControl("Footer1").Visible = false;
}
}
}

Yes just like that and our site’s header and footer will open the rules of visibility. Now, we are here because we have a high performance web and it has not view state, no session, what so ever. All login and security measure depends on cookie and each request.


More over we have output caching enabled on header and footer for “9000”.


What will happen when control has Output Cache defined


I am sure all of you know that you can cache page, user control's  output cache, it’s a default asp.net attribute and can be added in any page and user control to cache output for a object for particular period of time with some parameter or customization. To do so we have to add “ <%@ OutputCache  Duration="9999" VaryByParam="none" %> “ in control or page declaration in html. to know more about it please visit http://msdn.microsoft.com/en-us/library/hdxfb6cy(v=vs.71).aspx.


What happen to the above code when we run the application in debug mode? The page works fine for the first time it works fine great!. what would happen if it try to access it again?, just hit inter in browser or refresh the  browser page, crap! its not working, showing server error and it says master page does not have this control eventually throws server error.


image



If you check if the control exists or not, first time it will return yes its exist second time it will say it does not exists. Its normal and its happening because the controls that we are trying to modify is cached, hence can’t be  access like that.


What is the solution then?


Solution is we have to find the cached control and then work on that control finally add it to the control again so that, what ever we have changed reflected on the page final output. Bellow the code segment is given for this. This time we have modified the code and kept it in master page, and just invoked a method from content page.


Master page’s code


using System;
using System.Web.UI;
using MasterPageControlExample.Controls;

namespace MasterPageControlExample
{
public partial class SiteMaster : MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{

}

public void DisplayHeader(bool value)
{
if(Header1!=null)
Header1.Visible = value;
else
{
var cachedHeader = (PartialCachingControl) Page.LoadControl(@"Controls\Header.ascx");
Page.Controls.Add(cachedHeader);
if(cachedHeader.CachedControl !=null)
{
var header = cachedHeader.CachedControl as Header;
if (header != null) header.Visible = value;
}
}
}

public void DisplayFooter(bool value)
{
if (Footer1 != null)
Footer1.Visible = value;
else
{
var cachedFooter = (PartialCachingControl)LoadControl(@"Controls\Footer.ascx");
Page.Controls.Add(cachedFooter);
if (cachedFooter.CachedControl != null)
{
var footer = cachedFooter.CachedControl as Footer;
if (footer != null) footer.Visible = value;
}
}
}
}
}


Content page’s code 


using System;

namespace MasterPageControlExample
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var masterPage = Master;
if (masterPage != null)
{
var siteMaster = (masterPage as SiteMaster);
if (siteMaster != null) siteMaster.DisplayHeader(false);
}
}
}
}


In above master page’s code we fist checked if the control is exists or not by simply checking null, for the first time it wont be null and can directly assign the properties, for the second and subsequent times until the control is been created once again when the cache expires the else block of the code will be executed.


In else block of DisplayHeader or DisplayFooter method we have Loaded the control, this time this Page.LoadControl method will return PartialCachingControl object. It have to be again added to Page.Controls to be able to access from CachedControl property of PartialCachingControl object. Finally added the required properties value.


Now this code will work on 100% case as we have over came the problem with output cache as well.


A good suggestion


Even if you are a beginner you probably know it but still sharing as some of us might not implemented it. I am talking about PageBase or ControlBase objects for asp.net site. The idea is just to reuse some repeating code and some other cross cutting concern if we have any in our page life cycle. Here I suggest that you create a BasePage.cs class where you will encapsulate the codes like display header and footer, and in content page you will just call this methods, in that case your code will in one place.


Bellow the code for BasePage.cs is given.


BasePage’s Code


namespace MasterPageControlExample.Objects
{
public class BasePage:System.Web.UI.Page
{
protected void DisplayHeader(bool value)
{
var masterPage = Master;
if (masterPage != null)
{
var siteMaster = (masterPage as SiteMaster);
if (siteMaster != null) siteMaster.DisplayHeader(value);
}
}

protected void DisplayFooter(bool value)
{
var masterPage = Master;
if (masterPage != null)
{
var siteMaster = (masterPage as SiteMaster);
if (siteMaster != null) siteMaster.DisplayFooter(value);
}
}
}
}

Content Page’s Code


using System;
using MasterPageControlExample.Objects;

namespace MasterPageControlExample
{
public partial class _Default : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
DisplayHeader(false);
}
}
}

This looks compact and organized now, when we manipulate some cached control it tend to create some inherent problems, some of the problems are discussed bellow.


problem: Adding control back in page.controls create server error


We can’t add the cached control in Page.Controls Object collection, since there is a good chance that the controls such as header or footer will have some tags that has server controls and that’s going to create problem while adding those controls in page.


Result of adding header back to Page.controls


image


Then what is the solution? we have to add in a placeholder where for this master page markup need to change so that header and footer will be declared declaratively in side a place holder.


Modified Master Page Code


<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" 
Inherits="MasterPageControlExample.SiteMaster" %>


<%@ Register Src="Controls/Header.ascx" TagName="Header" TagPrefix="uc1" %>
<%@ Register Src="Controls/Footer.ascx" TagName="Footer" TagPrefix="uc2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title></title>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form runat="server">
<div class="page">
<asp:PlaceHolder ID="PlaceHolderHeader" runat="server">
<uc1:Header ID="Header1" runat="server" />
</asp:PlaceHolder>
<div>
<h2>
<a href="Default.aspx">Default.aspx</a><br />
<a href="About.aspx">About.aspx</a><br />
<a href="Report.aspx">Report.aspx</a><br />
</h2>
</div>
<div class="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
<div class="clear">
</div>
</div>
<asp:PlaceHolder ID="PlaceHolderFooter" runat="server">
<uc2:Footer ID="Footer1" runat="server" />
</asp:PlaceHolder>
</form>
</body>
</html>


Note that in above code added two place holder to hold header and footer, and the header and footer which is user control added inside the place holder, now then if our intention is just to modify the visibility status there is a very easy way out again.


Here is the situation we have three content page



  1. Default page [where we want to display both header and footer]

  2. About page [where we want to display only header and hide footer]

  3. Report page [where we want to hide both header and footer]

Content page’s code in this scenario


//first page
public partial class _Default : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
DisplayHeader(true);
DisplayFooter(true);
}
}
//second page
public partial class About : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
DisplayHeader(true);
DisplayFooter(false);
}
}
//third page
public partial class Report : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
DisplayHeader(false);
DisplayFooter(false);
}
}

Master page’s code


public void DisplayHeader(bool value)
{
if(Header1!=null)
Header1.Visible = value;
else
{
Page.LoadControl(@"Controls\Header.ascx");
var cachingControl = PlaceHolderHeader.Controls[0] as StaticPartialCachingControl;
if (cachingControl != null) cachingControl.Visible = value;
}
}

public void DisplayFooter(bool value)
{
if (Footer1 != null)
Footer1.Visible = value;
else
{
LoadControl(@"Controls\Footer.ascx");
var cachingControl = PlaceHolderFooter.Controls[0] as StaticPartialCachingControl;
if (cachingControl != null) cachingControl.Visible = value;
}
}


Note that in this case I have cast the control[0] as the place holder as we have only one control inside the place holder,also note that you can’t set the custom properties here. As it’s a StaticPartialCachingControl.


problem: Setting other properties of the control other than visibility


Well this is the final part of the article in this section we want to set other properties of the cached control, unfortunately its not that much easy and there is not easy way out for setting properties in a cached control rather we have to load control and then add it back in control collection, but before change the desired property.


The intention is to change site title in About.aspx page. I am going to skip the rest of the other detail and list the code for master page. That will be self explanatory.


Master page’s code for Setting Site Title


public void SetSiteTitle(string siteTitle)
{
if (Header1 != null)
Header1.SiteTitle = siteTitle;
else
{
var cachedHeader = (PartialCachingControl)LoadControl(@"Controls\Header.ascx");
PlaceHolderHeader.Controls.Clear();
PlaceHolderHeader.Controls.Add(cachedHeader);
if (cachedHeader.CachedControl != null)
{
var header = cachedHeader.CachedControl as Header;
if (header != null) header.SiteTitle = siteTitle;
}
}
}


There are lots of thing that I want to list about this tiny little article but keeping some thing for the future. I hope I would get good feedback about this article.


Conclusion


In this short article we have seen a particular problem’s most easy way out, followed by what will happen when cached is enabled for a control, finally some tips and trick to make it perfect. The knowledge is available in web and can be found easily with single search in any search engine, however for beginners it’s a panic situation, and I have tried to organized the ideas sequentially so that it make sense in first read for a absolute beginner.


references


Tuesday, August 14, 2012

WPF Single instance application, Now a piece of cake,

I was thinking of making a single instance application, and in WPF, googled for a minute and found out this,

WPF application Single Instance in one line of code for usage

http://wpfsingleinstance.codeplex.com/

features

Usage: WpfSingleInstance.Make(); or WpfSingleInstance.Make(SingleInstanceModes.ForEveryUser);
1. Add only a line of code (above) in the App.xaml.cs or in the main window.
2. Add a small static class in project (and a dummy enum SingleInstanceModes).
No additional inheritance in App class.
No App.xalm deleting.
No so redundant WCF and Remoting.
It works by the EventWaitHandle. Look in code, it's so simply.

I like it, hope all will like it.

Included a single cs file in my project named “WpfSingleInstance.cs”

then added the following line

public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
WpfSingleInstance.Make();

base.OnStartup(e);
}
}


Man!! couldn’t get better than this, thanks to the contributor,

Until next time. Bye bye

Saturday, August 11, 2012

Amazing icon resources, available for free download!

Guys just found an amazing icon resources, probably you all know it but still sharing it. This is just fantastic people who would need icons for demo or just do some personal projects for self satisfaction can use this resources. All the icons are available for download with various pixel and with and height.

Check this out.

http://www.iconarchive.com/

Friday, August 3, 2012

WPF Tree view binding how to stuff.

Introduction

Treeview is a very useful control, yet not that much used in real life scenario, however; it has a very good potential and the control is very customizable. Even though it has some disadvantages over some special category of data but none the less this control is a great addition to WPF default control set. In this particular article we will look at some basic functionality that WPF Tree view can provides, in particular we will take a look at the binding options. 

Basic Uses

Bellow I have given a simple code, that shows how to add a treeview in XAML. The Treeview Items are also defined as as a child nodes.

<Window x:Class="WPFTreeView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TreeView Height="287"
HorizontalAlignment="Left"
Margin="12,12,0,0"
Name="treeView1"
VerticalAlignment="Top"
Width="479">
<TreeViewItem Header="Bing">
<TreeViewItem Header="A" />
<TreeViewItem Header="B" />
<TreeViewItem Header="C" />
</TreeViewItem>
<TreeViewItem Header="Google" >
<TreeViewItem Header="D" />
<TreeViewItem Header="E" />
</TreeViewItem>
<TreeViewItem Header="Yahoo" >
<TreeViewItem Header="F" />
</TreeViewItem>
</TreeView>
</Grid>
</Window>


 

If you want to Populate the tree view and its node from c# code bellow I have listed few line of code to demonstrate how to do that.


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

namespace WPFTreeView
{
public partial class WindowTreeViewFromCodexaml
{
private TreeView _treeView;

public WindowTreeViewFromCodexaml()
{
InitializeComponent();
BuildTreeView();
BuildTreeViewNodes(0,_treeView.Items);
}

private void BuildTreeViewNodes(int level, ItemCollection itemCollection)
{
if(level==3)
return;

for (int i = 0; i < 3; i++)
{
var item = new TreeViewItem();
item.Header = string.Format("Item {0}", i + 1);
BuildTreeViewNodes(level+1,item.Items);
itemCollection.Add(item);
}
}

private void BuildTreeView()
{
TreeViewContainer.Children.Clear();
_treeView = new TreeView();
_treeView.HorizontalAlignment = HorizontalAlignment.Left;
_treeView.Margin = new Thickness(12, 12, 0, 0);
_treeView.Name = "treeView1";
_treeView.VerticalAlignment = VerticalAlignment.Top;
TreeViewContainer.Children.Add(_treeView);
}
}
}


Binding to a source


In this section we would see how we can bind a Treeview to a data source which has a hierarchical structure. For this scenario let’s Consider the following example. “ We want to display employee information as hierarchical data. The corresponding xaml and c# code is given bellow. 


XAML code


<Window x:Class="WPFTreeView.WindowTreeViewWithItemSource"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowTreeViewWithItemSource" Height="300" Width="300">
<Window.Resources>
<HierarchicalDataTemplate x:Key="ItemTemplate" ItemsSource="{Binding Employees}" >
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}"></CheckBox>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<DockPanel LastChildFill="True">
<TreeView
Name="treeView1"
ItemTemplate="{StaticResource ItemTemplate}"
ItemsSource="{Binding Employees}">
</TreeView>
</DockPanel>
</Grid>
</Window>


Above  Xaml code shows declaration of WPF treeview where ItemSource is Employee Dependency Property. But we would assign the item source from code. And this would work perfectly as we override the binding with hard code source. We have also defined a item template for each tree view item node. Bellow the corresponding c# code is given.


C# code


public partial class WindowTreeViewWithItemSource
{
public WindowTreeViewWithItemSource()
{
InitializeComponent();
LoadData();
}

private void LoadData()
{
var employees = new List();
for (int i =1; i <= 100; i++)
{
var manager = new Employee {Name = string.Format("Manager {0}", i.ToString())};
for (int j = 1; j <= 100; j++)
{
var lead = new Employee { Name = string.Format("Team Lead {0}", i.ToString()) };
for (int k = 0; k < 100; k++)
{
var junior = new Employee { Name = string.Format("Developer {0}", i.ToString())};
lead.Employees.Add(junior);
}
manager.Employees.Add(lead);
}
employees.Add(manager);
}
treeView1.ItemsSource = employees;
}
}

public class Employee
{
public Employee()
{
Employees = new List();
}
public string Name { get; set; }
public string Department { get; set; }
public int Age { get; set; }
public string Designation { get; set; }
public string Email { get; set; }
public DateTime DateOfJoin { get; set; }
public double Salary { get; set; }
public List Employees { get; private set; }
}


In above code we have defined a custom user type named “Employee” and constructed a demo hierarchy data, and finally assigned to the item source of the treeview. Note that here we did assigned itemsouce directly. If we want to use binding in that case we have to use mvp (model view presenter) or MVVM ( Model View ViewModel) pattern.


public partial class WindowTreeViewWithItemSourceBinding
{
public WindowTreeViewWithItemSourceBinding()
{
InitializeComponent();
this.DataContext = new TreeViewPresenter();
}
}

public class TreeViewPresenter:DependencyObject
{
public TreeViewPresenter()
{
LoadData();
}
private void LoadData()
{
var employees = new List<Employee>();
for (int i = 1; i <= 100; i++)
{
var manager = new Employee { Name = string.Format("Manager {0}", i.ToString()) };
for (int j = 1; j <= 100; j++)
{
var lead = new Employee { Name = string.Format("Team Lead {0}", i.ToString()) };
for (int k = 0; k < 100; k++)
{
var junior = new Employee { Name =
                    string.Format("Developer {0}", i.ToString()) };
lead.Employees.Add(junior);
}
manager.Employees.Add(lead);
}
employees.Add(manager);
}
Employees = employees;
}
public List<Employee> Employees
{
get { return (List<Employee>)GetValue(EmployeesProperty); }
set { SetValue(EmployeesProperty, value); }
}

public static readonly DependencyProperty EmployeesProperty =
DependencyProperty.Register("Employees", typeof(List<Employee>),
typeof(TreeViewPresenter), new UIPropertyMetadata(null));
}


Summery


In this short article we have seen how to use WPF tree view and some usages of WPF tree view as far as the binding and populating tree view is concern.


References


MSDN Help