Here is the problem:
I want to sort a ListView when it is first loaded. I have implemented the functionality where in the List View can be sorted if the Header columns in the ListView are clicked.
I unable to find a suitable event which I can use to call my sort function. I tried using OnInitialized of the UserControl and Loaded events but it seems the List View is not populated when I call these functions.
I tried GotFocus of ListView. It works but then I have to click on the window to get the sorting done.
I want the sorting to be done as soon as the ListView is loaded.
I am using XML data binding with the List View. The ListView is part of a UserControl. The User Control is hosted in a MMC app.
Please let me know if you need any other information.
public class SortableGridViewColumn : GridViewColumn { public string SortPropertyName { get { return (string)GetValue(SortPropertyNameProperty); } set { SetValue(SortPropertyNameProperty, value); } }
// Using a DependencyProperty as the backing store for SortPropertyName. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SortPropertyNameProperty =
DependencyProperty.Register("SortPropertyName", typeof(string),
typeof(SortableGridViewColumn), new UIPropertyMetadata(""));
public bool IsDefaultSortColumn
{
get { return (bool)GetValue(IsDefaultSortColumnProperty); }
set { SetValue(IsDefaultSortColumnProperty, value); }
}
public static readonly DependencyProperty IsDefaultSortColumnProperty =
DependencyProperty.Register("IsDefaultSortColumn", typeof(bool),
typeof(SortableGridViewColumn), new UIPropertyMetadata(false));
}
public class SortableListView : ListView
{
public SortableListView()
{
}
SortableGridViewColumn lastSortedOnColumn = null;
ListSortDirection lastDirection = ListSortDirection.Ascending;
public void Sort(string sortBy, ListSortDirection direction)
{
ICollectionView dataView = CollectionViewSource.GetDefaultView
(this.ItemsSource);
//Check if dataView isn't null
if (dataView != null)
{
dataView.SortDescriptions.Clear();
SortDescription sd1 = new SortDescription("@isenabled", direction);
dataView.SortDescriptions.Add(sd1);
SortDescription sd = new SortDescription(sortBy, direction);
dataView.SortDescriptions.Add(sd);
dataView.Refresh();
}
}
private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
{
GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
if (headerClicked != null &&
headerClicked.Role != GridViewColumnHeaderRole.Padding)
{
// attempt to cast to the sortableGridViewColumn object.
SortableGridViewColumn sortableGridViewColumn = (headerClicked.Column) as SortableGridViewColumn;
// ensure that the column header is the correct type and a sort property has been set.
if (sortableGridViewColumn != null && !String.IsNullOrEmpty(sortableGridViewColumn.SortPropertyName))
{
ListSortDirection direction;
bool newSortColumn = false;
// determine if this is a new sort, or a switch in sort direction.
if (lastSortedOnColumn == null
|| String.IsNullOrEmpty(lastSortedOnColumn.SortPropertyName)
|| !String.Equals(sortableGridViewColumn.SortPropertyName, lastSortedOnColumn.SortPropertyName, StringComparison.InvariantCultureIgnoreCase))
{
newSortColumn = true;
direction = ListSortDirection.Ascending;
}
else
{
if (lastDirection == ListSortDirection.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
direction = ListSortDirection.Ascending;
}
}
// get the sort property name from the column's information.
string sortPropertyName = sortableGridViewColumn.SortPropertyName;
// Sort the data.
Sort(sortPropertyName, direction);
lastSortedOnColumn = sortableGridViewColumn;
lastDirection = direction;
}
}
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
// add the event handler to the GridViewColumnHeader. This strongly ties this ListView to a GridView.
this.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(GridViewColumnHeaderClickedHandler));
// cast the ListView's View to a GridView
GridView gridView = this.View as GridView;
if (gridView != null)
{
// determine which column is marked as IsDefaultSortColumn. Stops on the first column marked this way.1
SortableGridViewColumn sortableGridViewColumn = null;
foreach (GridViewColumn gridViewColumn in gridView.Columns)
{
sortableGridViewColumn = gridViewColumn as SortableGridViewColumn;
if (sortableGridViewColumn != null)
{
if (sortableGridViewColumn.IsDefaultSortColumn)
{
break;
}
sortableGridViewColumn = null;
}
}
// if the default sort column is defined, sort the data
if (sortableGridViewColumn != null)
{
lastSortedOnColumn = sortableGridViewColumn;
Sort(sortableGridViewColumn.SortPropertyName, ListSortDirection.Ascending);
}
}
}
}
The XAML is as shown below:
**<local:SortableListView x:Name="ListViewControl" Grid.Row="0" ItemContainerStyle="{DynamicResource StretchedContainerStyle}"
ItemTemplateSelector="{DynamicResource myControlTemplateSelector}"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Source={StaticResource dataProvider},
XPath=//CONFIGURATION}">
<ListView.View >
<GridView >
<local:SortableGridViewColumn Header="ID" HeaderContainerStyle="{StaticResource CustomHeaderStyle}"
DisplayMemberBinding="{Binding XPath=./@id}"
IsDefaultSortColumn="True"
SortPropertyName="@id"/>
<local:SortableGridViewColumn Header="VALUE" HeaderContainerStyle="{StaticResource CustomHeaderStyle}"
CellTemplateSelector="{DynamicResource myControlTemplateSelector}"
SortPropertyName="@value"/>
<local:SortableGridViewColumn Header="DATATYPE" HeaderContainerStyle="{StaticResource CustomHeaderStyle}"
DisplayMemberBinding="{Binding XPath=./@data_type}"
SortPropertyName="@data_type"/>
<local:SortableGridViewColumn Header="DESCRIPTION" HeaderContainerStyle="{StaticResource CustomHeaderStyle}"
DisplayMemberBinding="{Binding XPath=./@description}"
SortPropertyName="@description"
Width="{Binding ElementName=ListViewControl, Path=ActualWidth}"/>
</GridView>
</ListView.View>
</local:SortableListView>**
<StackPanel Grid.Row="1">
<Button Grid.Row="1" HorizontalAlignment="Stretch" Height="34" HorizontalContentAlignment="Stretch" >
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Center" Orientation="Horizontal" FlowDirection="RightToLeft" Height="30">
<Button Grid.Row="1" Content ="Apply" Padding="0,0,0,0 " Margin="6,2,0,2" Name="btn_Apply" HorizontalAlignment="Right" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Width="132" IsTabStop="True" Click="btn_ApplyClick" Height="24" />
</StackPanel >
</Button>
</StackPanel >
</Grid>