Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><a href="http://msdn.microsoft.com/en-us/library/ms745786.aspx">MSDN has an easy way to perform sorting on columns</a> with up/down glyphs. The example isn't complete, though - they don't explain how to use the data templates for the glyphs. Below is what I got to work with my ListView. This works on .Net 4.</p> <p>In your ListView, you have to specify an event handler to fire for a click on the GridViewColumnHeader. My ListView looks like this:</p> <pre><code>&lt;ListView Name="results" GridViewColumnHeader.Click="results_Click"&gt; &lt;ListView.View&gt; &lt;GridView&gt; &lt;GridViewColumn DisplayMemberBinding="{Binding Path=ContactName}"&gt; &lt;GridViewColumn.Header&gt; &lt;GridViewColumnHeader Content="Contact Name" Padding="5,0,0,0" HorizontalContentAlignment="Left" MinWidth="150" Name="ContactName" /&gt; &lt;/GridViewColumn.Header&gt; &lt;/GridViewColumn&gt; &lt;GridViewColumn DisplayMemberBinding="{Binding Path=PrimaryPhone}"&gt; &lt;GridViewColumn.Header&gt; &lt;GridViewColumnHeader Content="Contact Number" Padding="5,0,0,0" HorizontalContentAlignment="Left" MinWidth="150" Name="PrimaryPhone"/&gt; &lt;/GridViewColumn.Header&gt; &lt;/GridViewColumn&gt; &lt;/GridView&gt; &lt;/ListView.View&gt; &lt;/ListView&gt; </code></pre> <p>In your code behind, set up the code to handle the sorting:</p> <pre><code>// Global objects BindingListCollectionView blcv; GridViewColumnHeader _lastHeaderClicked = null; ListSortDirection _lastDirection = ListSortDirection.Ascending; // Header click event void results_Click(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 &amp;&amp; _lastHeaderClicked != headerClicked) { _lastHeaderClicked.Column.HeaderTemplate = null; } _lastHeaderClicked = headerClicked; _lastDirection = direction; } } // Sort code private void Sort(string sortBy, ListSortDirection direction) { blcv.SortDescriptions.Clear(); SortDescription sd = new SortDescription(sortBy, direction); blcv.SortDescriptions.Add(sd); blcv.Refresh(); } </code></pre> <p>And then in your XAML, you need to add two DataTemplates that you specified in the sorting method:</p> <pre><code>&lt;DataTemplate x:Key="HeaderTemplateArrowUp"&gt; &lt;DockPanel LastChildFill="True" Width="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GridViewColumnHeader}}}"&gt; &lt;Path x:Name="arrowUp" StrokeThickness="1" Fill="Gray" Data="M 5,10 L 15,10 L 10,5 L 5,10" DockPanel.Dock="Right" Width="20" HorizontalAlignment="Right" Margin="5,0,5,0" SnapsToDevicePixels="True"/&gt; &lt;TextBlock Text="{Binding }" /&gt; &lt;/DockPanel&gt; &lt;/DataTemplate&gt; &lt;DataTemplate x:Key="HeaderTemplateArrowDown"&gt; &lt;DockPanel LastChildFill="True" Width="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GridViewColumnHeader}}}"&gt; &lt;Path x:Name="arrowDown" StrokeThickness="1" Fill="Gray" Data="M 5,5 L 10,10 L 15,5 L 5,5" DockPanel.Dock="Right" Width="20" HorizontalAlignment="Right" Margin="5,0,5,0" SnapsToDevicePixels="True"/&gt; &lt;TextBlock Text="{Binding }" /&gt; &lt;/DockPanel&gt; &lt;/DataTemplate&gt; </code></pre> <p>Using the <code>DockPanel</code> with <code>LastChildFill</code> set to true will keep the glyph on the right of the header and let the label fill the rest of the space. I bound the <code>DockPanel</code> width to the <code>ActualWidth</code> of the <code>GridViewColumnHeader</code> because my columns have no width, which lets them autofit to the content. I did set <code>MinWidth</code>s on the columns, though, so that the glyph doesn't cover up the column title. The <code>TextBlock Text</code> is set to an empty binding which displays the column name specified in the header.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload