Search content within the blog

Friday, July 29, 2011

Sql Server : Top 10 cached queries.

In this article, we will see how to view the most cached statements on the server.

The view sys.dm_exec_cached_plans and function dm_exec_sql_text can be used for this purpose.

Let us execute the following query

sql-server-dmv-cache
select top 10
db_name(sql_text.dbid) as db_name,
cache_plan.objtype,
sql_text.text ,
cache_plan.usecounts
from
sys.dm_exec_cached_plans as cache_plan
cross apply sys.dm_exec_sql_text(plan_handle) as sql_text
order by
usecounts desc

Here are some important points to note about this query:

The result is based on the descending order of the column ‘usecounts’ which is used to indicate the number of times the cached objects are used.
The column ‘object type’ indicates whether the statement is of the type procedure,view, adhoc etc.
The column text shows the exact statement which was cached.
The column db_name is null for the cached types adhoc, prepared, etc





OUTPUT

Thursday, July 28, 2011

Managing cookies in WPF

A cookie is an arbitrary piece of data that can be stored by an application on the client machine during application sessions (session cookies) or across application sessions (persistent cookies). You can create both types of cookies by calling SetCookie.

Cookie data typically takes the form of a name/value pair in the following format:

Name=Value

You pass a string of this format to SetCookie, along with the Uri of the location for which the cookie should be set (typically, the application domain).

Whether a cookie is a session cookie or a persistent cookie depends on whether the cookie string that you pass to SetCookie includes an expiry date. The string for a session cookie does not include an expiry date. The string for a persistent cookie does, and must be in the following format:

NAME=VALUE; expires=DAY, DD-MMM-YYYY HH:MM:SS GMT

Persistent cookies are stored in the current Windows installation's Temporary Internet Files folder until they expire, in which case they are deleted. You can delete a persistent cookie from your application by setting its expiry date to a date/time value that is in the past.


Code snippet in Listing 1 creates two cookies using SetCookie method. One is a session cookie and other is a persistent cookie.

string simpleCookie = "CSCUser1=Mahesh";
string cookieWithExpiration = "CSCUser2=Mahesh;expires=Sat, 10-Oct-2012 00:00:00 GMT";


Listing 1
Uri cookieUri1 = new Uri(@"C:\Junk\SimpleMC");
Uri cookieUri2 = new Uri(@"C:\Junk\PersMC");

Application.SetCookie(cookieUri1, simpleCookie);
Application.SetCookie(cookieUri2, cookieWithExpiration);


Application.GetCookie method retrieves cookie data from the given Uri.
The code listed in Listing 2 uses the GetCookie method to get the cookie data and displays it in a MessageBox.

Listing 2
Uri cookiePath = new Uri(@"C:\Junk\SimpleMC");
string cookie = Application.GetCookie(cookiePath);
MessageBox.Show(cookie);

Drawing Shapes in WPF

Drawing Shapes in WPF
This article is an introduction to graphics programming in XAML and WPF. In this article, I discuss various graphics objects including lines, rectangles, ellipses, and paths and how to draw them using XAML and WPF.

Drawing a Line


The Line tag of XAML draws a line. The X1,Y1 and X2,Y2 attributes represent the starting and ending point of the line and Stroke represents the color of the line. The StrokeThickness attribute represents the thickness of the line.

The following code draws a line from point (100,100) t (300,100) with blue color and thickness is 2.

<Line Stroke="#000fff" StrokeThickness="2" X1="100" Y1="100"

X2="300" Y2="100"/>

The output looks like Figure 1.

Figure 1. Drawing a line




Drawing and Filling a Rectangle


The Rectangle tag of XAML draws a rectangle. The Height and Width attributes represent the height and width of the rectangle. The Stroke and StrokeThickness represents the color and thickness of the rectangle boundary.

The following code draws a rectangle with height 100 and width 300.

<Rectangle Width="300" Height="100" Stroke="Blue" StrokeThickness="5">

</Rectangle>

The output looks like Figure 2.

Figure 2. Drawing a rectangle



The Fill attributes fill a rectangle with a color. The following code fills a rectangle with yellow color.

Rectangle Fill="Yellow" Width="300" Height="100" Stroke="Blue"

StrokeThickness="5">

</Rectangle>

The output looks like Figure 3.

Figure 3. Filling a rectangle





By setting RadiusX and RadiusY attributes, you can also draw a rectangle with rounded corners.

<Rectangle Width="120" Height="100" RadiusX="10" RadiusY="10"

Stroke="Green" StrokeThickness="5" Fill="Black">

</Rectangle>

The output looks like Figure 4.

Figure 4. Drawing a rounded rectangle




Drawing and Filling an Ellipse


The Ellipse tag of XAML draws an ellipse and circle (ellipse with equal height and width). The Height and Width attributes represent the height and width of the ellipse. The Stroke and StrokeThickness represents the color and thickness of the ellipse boundary. The Fill attribute fills the ellipse with a color.

The following code draws an ellipse with height 100 and width 300.

<Ellipse Height="100" Width="300" StrokeThickness="5" Stroke="Black" Fill="Gold"/>

The output looks like Figure 5.

Figure 5. Drawing and Filling an Ellipse





Drawing and Filling a Path


The Path tag of XAML draws a path. The Data attribute of the Path represents various points in the path. Here M represents MoveTo command and C represents the absolute path. Capital H represents the LineTo command.

The following code draws a path.

<Path Data="M 200,40 C 50,90 200,250 200,75 H 300" Stroke="Black" StrokeThickness="4"/>

The output looks like Figure 6.

Figure 6. Drawing a path






Similar to the rectangle and ellipse, the Fill attribute fills a path with a color.

<Path Data="M 200,40 C 50,90 200,250 200,75 H 480" Stroke="Black"

StrokeThickness="4" Fill="Yellow"/>

The output looks like Figure 7.

Figure 7. Filling a path



Drawing and Filling a Polygon

The <Polygon /> tag of XAML draws a ploygon. The Points attribute represents various points of the polygon.

The following code draws and fills a polygon.

<Polygon Points="100,50 50,100 150,100 100,50 100,30" Stroke="Green" StrokeThickness="3" Fill="Yellow"/>

The output looks like Figure 8.

Figure 8. Drawing and filling a polygon




Here is another example of a polygon.

<Polygon Points="100,0 75,75 100,100 125,75"

Stroke="Black" StrokeThickness="2" Fill="Yellow"/>

<Polygon Points="100,100 125,125 100,200 75,125"

Stroke="Yellow" StrokeThickness="2" Fill="Black"/>

<Polygon Points="100,100 125,75 200,100 125,125"

Stroke="Red" StrokeThickness="2" Fill="Blue"/>

<Polygon Points="100,100 75,125 0,100 75,75"

Stroke="Blue" StrokeThickness="2" Fill="Red"/>


The output looks like Figure 9.

Figure 9. Nice looking polygon



Drawing a Polyline

The <Polyline /> tag of XAML draws a ployline, which is a series of connected lines. Unlike a polygon, which is a closed curver, a polyline is usually an open curve. If you want to draw a series of connected lines but closed curve, you might want to use polygon.

Similar to the polygon, a polyline has Points attribute that defines the points of lines draw from and to. The following code draws a ployline.

<Polyline Points="50,100 150,100 100,50 250,50" Stroke="Blue" StrokeThickness="2"/>

The output looks like Figure 10.

Figure 10. Drawing a polyline

Transferring data between ListBoxes in WPF.

This article shows us how data can be transferred from one listbox to another in WPF.
For the demo purpose the listbox is binded to a arraylist, in reality it may obtain data from the database, a collection of objects ot from XML file.

The code is self explanatory,

XAML
<Window x:Class="WPFControlsSample.TwoListBoxes"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TwoListBoxes" Height="300" Width="606" Loaded="Window_Loaded">
<Grid>
<ListBox Margin="11,13,355,11" Name="LeftListBox" />
<ListBox Margin="0,13,21,11" Name="RightListBox" HorizontalAlignment="Right" Width="216" />
<Button Name="AddButton" Height="23" Margin="248,78,261,0" VerticalAlignment="Top"
Click="AddButton_Click">Add >></Button>
<Button Name="RemoveButton" Margin="248,121,261,117"
Click="RemoveButton_Click"><< Remove</Button>
</Grid>
</Window>


XAML.CS


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.Shapes;
using System.Collections;

namespace WPFControlsSample
{
/// <summary>
/// Interaction logic for TwoListBoxes.xaml
/// </summary>
public partial class TwoListBoxes : Window
{
private ArrayList myDataList = null;
string currentItemText ;
int currentItemIndex ;

public TwoListBoxes()
{
InitializeComponent();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Get data from somewhere and fill in my local ArrayList
myDataList = LoadListBoxData();
// Bind ArrayList with the ListBox
LeftListBox.ItemsSource = myDataList;
}

/// <summary>
/// Generate data. This method can bring data from a database or XML file
/// or from a Web service or generate data dynamically
/// </summary>
/// <returns></returns>
private ArrayList LoadListBoxData()
{
ArrayList itemsList = new ArrayList();
itemsList.Add("Coffie");
itemsList.Add("Tea");
itemsList.Add("Orange Juice");
itemsList.Add("Milk");
itemsList.Add("Mango Shake");
itemsList.Add("Iced Tea");
itemsList.Add("Soda");
itemsList.Add("Water");
return itemsList;
}

private void AddButton_Click(object sender, RoutedEventArgs e)
{
// Find the right item and it's value and index
currentItemText = LeftListBox.SelectedValue.ToString();
currentItemIndex = LeftListBox.SelectedIndex;

RightListBox.Items.Add(currentItemText);
if (myDataList != null)
{
myDataList.RemoveAt(currentItemIndex);
}

// Refresh data binding
ApplyDataBinding();
}

private void RemoveButton_Click(object sender, RoutedEventArgs e)
{
// Find the right item and it's value and index
currentItemText = RightListBox.SelectedValue.ToString();
currentItemIndex = RightListBox.SelectedIndex;
// Add RightListBox item to the ArrayList
myDataList.Add(currentItemText);

// LeftListBox.Items.Add(RightListBox.SelectedItem);
RightListBox.Items.RemoveAt(RightListBox.Items.IndexOf(RightListBox.SelectedItem));

// Refresh data binding
ApplyDataBinding();
}

/// <summary>
/// Refreshes data binding
/// </summary>
private void ApplyDataBinding()
{
LeftListBox.ItemsSource = null;
// Bind ArrayList with the ListBox
LeftListBox.ItemsSource = myDataList;
}
}
}

Creating Fancy Tooltips in WPF

Each control in WPF has a Tooltip property that can be accessed through XAML or code behind. The Tooltip property can host any kind of controls such as a rectangle, text block, or a panel. In other words, we can display another window with any number of controls as a tooltip of a control.

The following code creates a simple tooltip for a button control.

<Button Width="100" Height="30">Click Me

<Button.ToolTip>

<ToolTip>This is a tooltip test for a button control. You

can click me if you want but I will do nothing for you.

</ToolTip>

</Button.ToolTip>

</Button>

The output looks like the one in the figure below,



As I said earlier, a Tooltip can host any number of controls. For example, in the below code, a button tooltip hosts a StackPanel with two children StackPanels. First StackPanel hosts an image and a text block and second StackPanel hosts a larger textblock. The output looks like Figure 2, which is a fancy tooltip.

<Button Width="100" Height="30">Click Me

<Button.ToolTip>

<StackPanel Background="Honeydew" Height="200" Width="200">

<StackPanel Background="BurlyWood" Height="30" Width="200" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" >

<Image VerticalAlignment="Top" Width="30" Height="30" Source="C:\Projects\XAML\FancyTooltip\FancyTooltip\samp.png" Name="image1" />

<TextBlock FontFamily="Aharoni" FontSize="24" FontWeight="Bold" Foreground="Black" TextWrapping="Wrap" VerticalAlignment="Top" Height="30" HorizontalAlignment="Right" Width="143">

<Run FontFamily="Andalus" FontSize="18" FontWeight="Normal" Text="Hello! Fancy Tip"/>

</TextBlock>

</StackPanel>



<StackPanel Width="200" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" >

<TextBlock TextWrapping="Wrap" Foreground="#FFF9F4F4" TextAlignment="Center" Background="{x:Null}" HorizontalAlignment="Right" VerticalAlignment="Top" Width="181" Height="98">

<Run FontFamily="Verdana" FontSize="11" FontWeight="Normal" Foreground="#FF151514"

Text="Format your tip the way you want and put any image, text or other controls on it.

Also, you can add more controls in this tip the way you want to format it."/>

</TextBlock>

</StackPanel>

</StackPanel>

</Button.ToolTip>

</Button>


Figure 2




Using this approach, you may design your tooltips the way you want.

Note: In the above code, you may want to change the source of the image file by changing the following code: Source="C:\Projects\XAML\FancyTooltip\FancyTooltip\samp.png"

Tuesday, July 26, 2011

Two way Binding in WPF

In this article we shall understand two way binding in WPF applications.

Abstract :

In this article I will show you about two way binding in WPF application. Its very easy to do in WPF in comparison of windows Application programming.

Two way binding is used when we want to update some controls property when some other related controls property change and when source property change the actual control also updates its property. I think this sentence is hard to understand :)

Let me explain you with an example.

Suppose we have one one Slider control and one textbox. Now if I move slider its value should be displayed in text box and when I input some value in textbox it should be reflected in Slider too.. that's called two way binding .. :)

Implementation :

We will create sample application that will demonstrate the same as I mentioned in abstract part of the article.

Start with File >> New >>Projects >>Visual C# >> WPF Application ...

DragDrop One Slider control on the WPF form ..and a Textbox ..Setup the GUI like shown in below image






Now we want to bind TextBox Text Property to the Slider's value property ..
In XAML code of TextBox we will write Text Property as below

Text="{Binding Mode=OneWayToSource, ElementName=Slider1,Path=Value, UpdateSourceTrigger=PropertyChanged}

Lets understand what it says
Mode : Specify how we want to Bind Control
here we will have default, OneTime, OneWay ,OneWayToSource, TwoWay.

OneTime: changes Slider Property one time only when we write value in Text box
OneWay: Only Text box Property will be updated when we move Slider ..but if we write some value in TextBox it will not be reflected in Slider
OneWayToSource: by this option we can update the Value of Slider from Text box but can not Update value of textBox from Slider.
TwoWay: if we update the value of textbox it will be reflated to Slider and If we update the value of slider it will be reflected in TextBox .

Now when we bind something we need to specify which control we are binding so
ElemenetName : Specify which control to bind ..

Path Specifies which specific property we are trying to bind here we are using Value property becuase we want to Bind Value property of the Slider to TextBox

UpdateSourceTrigger: it specifies when trigger should be fired .. we specified when some PropertyChanged in Source .

Here is My Full XAML Code of Grid take a look ..

<Window x:Class="TwowayBinding.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>

<Slider Name="Slider1" Value="0" Margin="84,85,173,199" SmallChange="1" Maximum="100" ></Slider>

<TextBox Name="txtValue" Margin="84,118,173,174" Text="{Binding Mode=TwoWay, ElementName=Slider1,Path=Value, UpdateSourceTrigger=PropertyChanged}"></TextBox>

<Label Content="Value " Height="28" HorizontalAlignment="Left" Margin="39,114,0,0" Name="label1" VerticalAlignment="Top" />

<Label Content="Two way binding Demo :" Height="61" HorizontalAlignment="Left" Margin="17,12,0,0" Name="label2" VerticalAlignment="Top" FontSize="32" />

</Grid>
</Window>


Just write the code like it and Run the project ..
You have successfully learned how to bind Two Controls Two way . :)
Thank you for reading article :)

Styles in WPF

The following sample shows how styles can be applied at page level in WPF. The style details are encapsulated under <Window.Resources> tags. Each style that you create must have a unique name associated with it. This is done by the key property.
Setting the Key property to unique names created unique style elements. The creation of style is very similar to the way it is done in web applications.

Once the style elements are created we need to associate the control with the style name.

Note: We specify the style as "Control.Property" example "TextBlock.Background" the reason being some of the controls do not understand when you just specify the property that you want to modify or style. Example a "TextBlock" does not understand when you just say "Background". You need to explicitly specify "Control.Property" for it to work properly.



XAML Code.

<Window x:Class="applystyles_cs.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="applystyles_cs" Height="300" Width="300"
>
<Window.Resources>

<Style x:Key="myTextstyle">
<Setter Property="TextBlock.Background" Value="Black" />
<Setter Property="TextBlock.Margin" Value="10,10,10,5" />
<Setter Property="TextBlock.Foreground" Value="White" />
<Setter Property="TextBlock.FontSize" Value="20" />
<Setter Property="TextBlock.HorizontalAlignment" Value="Center" />
</Style>

<Style x:Key="btnstyle">
<Setter Property="Button.Margin" Value="10,5,10,10" />
<Setter Property="Button.Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Blue" />
<GradientStop Offset="1" Color="Red" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Button.HorizontalAlignment" Value="Center" />
</Style>

</Window.Resources>

<StackPanel>
<TextBlock Style="{StaticResource myTextstyle}">
Hello
</TextBlock>
<Button Style="{StaticResource btnstyle}">
Click Me</Button>
</StackPanel>
</Window>

WPF Message box

The sample demonstrates the use of message box in WPF. it also shows the various options available for the WPF message box parameters like "caption", "image to be shown", "MessageBoxText".


The code/example is self explanatory .Just copy paste the code in the XAML and it's code behind file.


XAML Code
<Window x:Class="MessageBoxSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MessageBoxSample" Height="300" Width="500"
>
<Grid>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>

<Label Grid.Column="0" Grid.Row="0">Associate with Owner Window?</Label>
<CheckBox Grid.Column="1" Grid.Row="0" Name="ownerCheckBox"></CheckBox>

<Label Grid.Column="0" Grid.Row="1">messageBoxText:</Label>
<TextBox Grid.Column="1" Grid.Row="1" Name ="messageBoxText">MessageBoxText</TextBox>

<Label Grid.Column="0" Grid.Row="2">caption:</Label>
<TextBox Grid.Column="1" Grid.Row="2" Name="caption">Caption</TextBox>

<Label Grid.Column="0" Grid.Row="3">button:</Label>
<ComboBox Grid.Column="1" Grid.Row="3" Name="buttonComboBox">
<ComboBoxItem IsSelected="True">OK</ComboBoxItem>
<ComboBoxItem>OKCancel</ComboBoxItem>
<ComboBoxItem>YesNo</ComboBoxItem>
<ComboBoxItem>YesNoCancel</ComboBoxItem>
</ComboBox>

<Label Grid.Column="0" Grid.Row="4">icon:</Label>
<ComboBox Grid.Column="1" Grid.Row="4" Name="imageComboBox">
<ComboBoxItem>Asterisk</ComboBoxItem>
<ComboBoxItem>Error</ComboBoxItem>
<ComboBoxItem>Exclamation</ComboBoxItem>
<ComboBoxItem>Hand</ComboBoxItem>
<ComboBoxItem>Information</ComboBoxItem>
<ComboBoxItem IsSelected="True">None</ComboBoxItem>
<ComboBoxItem>Question</ComboBoxItem>
<ComboBoxItem>Stop</ComboBoxItem>
<ComboBoxItem>Warning</ComboBoxItem>
</ComboBox>

<Label Grid.Column="0" Grid.Row="5">defaultResult:</Label>
<ComboBox Grid.Column="1" Grid.Row="5" Name="defaultResultComboBox">
<ComboBoxItem>Cancel</ComboBoxItem>
<ComboBoxItem>No</ComboBoxItem>
<ComboBoxItem IsSelected="True">None</ComboBoxItem>
<ComboBoxItem>OK</ComboBoxItem>
<ComboBoxItem>Yes</ComboBoxItem>
</ComboBox>

<Label Grid.Column="0" Grid.Row="6">options</Label>
<ComboBox Grid.Column="1" Grid.Row="6" Name="optionsComboBox">
<ComboBoxItem>DefaultDesktopOnly</ComboBoxItem>
<ComboBoxItem IsSelected="True">None</ComboBoxItem>
<ComboBoxItem>RightAlign</ComboBoxItem>
<ComboBoxItem>RtlReading</ComboBoxItem>
<ComboBoxItem>ServiceNotification</ComboBoxItem>
</ComboBox>

<Button Grid.Column="1" Grid.Row="7" Name="showMessageBoxButton" Click="showMessageBoxButton_Click">Show MessageBox</Button>

<StatusBar Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="8" >
<StatusBarItem>
<TextBlock Name="resultTextBlock">Ready</TextBlock>
</StatusBarItem>
</StatusBar>

</Grid>

</Window>






XAML.CS code


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 MessageBoxSample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

void showMessageBoxButton_Click(object sender, RoutedEventArgs e)
{
// Configure the message box
Window owner = ((bool)ownerCheckBox.IsChecked ? this : null);
string messageBoxText = this.messageBoxText.Text;
string caption = this.caption.Text;
MessageBoxButton button = (MessageBoxButton)Enum.Parse(typeof(MessageBoxButton), this.buttonComboBox.Text);
MessageBoxImage icon = (MessageBoxImage)Enum.Parse(typeof(MessageBoxImage), this.imageComboBox.Text);
MessageBoxResult defaultResult = (MessageBoxResult)Enum.Parse(typeof(MessageBoxResult), this.defaultResultComboBox.Text);
MessageBoxOptions options = (MessageBoxOptions)Enum.Parse(typeof(MessageBoxOptions), this.optionsComboBox.Text);

// Show message box, passing the window owner if specified
MessageBoxResult result;
if (owner == null)
{
result = MessageBox.Show(messageBoxText, caption, button, icon, defaultResult, options);
}
else
{
result = MessageBox.Show(owner, messageBoxText, caption, button, icon, defaultResult, options);
}

// Show the result
resultTextBlock.Text = "Result = " + result.ToString();
}
}
}

Monday, July 25, 2011

WPF - Sort a GridView Column When a Header Is Clicked

In this post we shall learn how to Sort a GridView Column When a Header Is Clicked

The Listview contains its view as a Gridview. The Giridview is bound to a Arraylist which is a collection of dates.

The Gridview data is sorted when a header column of Giridview is clicked.

Note: The declaration that says that "Sort the Gridview data when a header column is clicked is defined in Listview".


XAML content.


<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ListViewSort.Window1"
xmlns:s="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:p="clr-namespace:System;assembly=mscorlib">
<Window.Resources>
<DataTemplate x:Key="HeaderTemplateArrowUp">
<DockPanel>
<TextBlock HorizontalAlignment="Center" Text="{Binding}"/>
<Path x:Name="arrow"
StrokeThickness = "1"
Fill = "gray"
Data = "M 5,10 L 15,10 L 10,5 L 5,10"/>
</DockPanel>
</DataTemplate>
<DataTemplate x:Key="HeaderTemplateArrowDown">
<DockPanel>
<TextBlock HorizontalAlignment="Center" Text="{Binding }"/>
<Path x:Name="arrow"
StrokeThickness = "1"
Fill = "gray"
Data = "M 5,5 L 10,10 L 15,5 L 5,5"/>
</DockPanel>
</DataTemplate>
</Window.Resources>

<StackPanel>
<TextBlock HorizontalAlignment="Center" FontSize="16"
Foreground ="Blue" Margin="0,20,0,30">
ListView Sample with Sort Capability
</TextBlock>
<ListView x:Name='lv' Height="150" HorizontalAlignment="Center"
VerticalAlignment="Center"
GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler"
>
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=Year}"
Header="Year"
Width="100"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=Month}"
Header="Month"
Width="100"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=Day}"
Header="Day"
Width="100"/>
</GridView>
</ListView.View>
<ListView.ItemsSource>
<s:ArrayList>
<p:DateTime>1993/1/1 12:22:02</p:DateTime>
<p:DateTime>1993/1/2 13:2:01</p:DateTime>
<p:DateTime>1997/1/3 2:1:6</p:DateTime>
<p:DateTime>1997/1/4 13:6:55</p:DateTime>
<p:DateTime>1999/2/1 12:22:02</p:DateTime>
<p:DateTime>1998/2/2 13:2:01</p:DateTime>
<p:DateTime>2000/2/3 2:1:6</p:DateTime>
<p:DateTime>2002/2/4 13:6:55</p:DateTime>
<p:DateTime>2001/3/1 12:22:02</p:DateTime>
<p:DateTime>2006/3/2 13:2:01</p:DateTime>
<p:DateTime>2004/3/3 2:1:6</p:DateTime>
<p:DateTime>2004/3/4 13:6:55</p:DateTime>
</s:ArrayList>
</ListView.ItemsSource>
</ListView>

</StackPanel>
</Window>



XAML.CS - Code behind



using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Collections;
using System.Windows.Controls.Primitives;
using System.ComponentModel;
using System.Windows.Data;

namespace ListViewSort
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}

GridViewColumnHeader _lastHeaderClicked = null;
ListSortDirection _lastDirection = ListSortDirection.Ascending;

void GridViewColumnHeaderClickedHandler(object sender,
RoutedEventArgs e)
{
GridViewColumnHeader headerClicked =
e.OriginalSource as GridViewColumnHeader;
ListSortDirection direction;

if (headerClicked != null)
{
if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
{
if (headerClicked != _lastHeaderClicked)
{
direction = ListSortDirection.Ascending;
}
else
{
if (_lastDirection == ListSortDirection.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
direction = ListSortDirection.Ascending;
}
}

string header = headerClicked.Column.Header as string;
Sort(header, direction);

if (direction == ListSortDirection.Ascending)
{
headerClicked.Column.HeaderTemplate =
Resources["HeaderTemplateArrowUp"] as DataTemplate;
}
else
{
headerClicked.Column.HeaderTemplate =
Resources["HeaderTemplateArrowDown"] as DataTemplate;
}

// Remove arrow from previously sorted header
if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
{
_lastHeaderClicked.Column.HeaderTemplate = null;
}


_lastHeaderClicked = headerClicked;
_lastDirection = direction;
}
}
}
private void Sort(string sortBy, ListSortDirection direction)
{
ICollectionView dataView =
CollectionViewSource.GetDefaultView(lv.ItemsSource);

dataView.SortDescriptions.Clear();
SortDescription sd = new SortDescription(sortBy, direction);
dataView.SortDescriptions.Add(sd);
dataView.Refresh();
}
}
}