0

I am beginner at WPF. I am trying to sort (asc/desc) a listview by clicking a column. I have binded an observable collection to my listview. I have tried something I have found here https://msdn.microsoft.com/en-us/library/ms745786(v=vs.110).aspx For some reason it doesn't work on me. My code is almost same within this link here. But I wrote it here anyways though sorry that it's a little bit long.

I made some search and many answer already suggests exactly what I did. So I guess I made some mistakes somewhere.

Here is WPF:

    <ListView Grid.Row="3" Name="lvPurchaseSummaryList" ItemsSource="{Binding purchaseSummaryCol, Mode=Default}" Width="1700" HorizontalAlignment="Left" GridViewColumnHeader.Click="purchaseSummaryListColumn_click">
        <ListView.View>
            <GridView>
                <GridViewColumn Width="100" DisplayMemberBinding="{Binding Path=originalName}" Header="Original Name" />
                <GridViewColumn Width="100" DisplayMemberBinding="{Binding Path=turkishName}" Header="Local Name"/>
 // List goes on like this...
            </GridView>
        </ListView.View>
</ListView>

Here is the class (almost same with msdn link):

public partial class PurchaseSummaryPage : Page
{
    GridViewColumnHeader _lastHeaderClicked = null;
    ListSortDirection _lastDirection = ListSortDirection.Ascending;
    public PurchaseSummaryPage()
    {
        InitializeComponent();  
    }

    void purchaseSummaryListColumn_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 && _lastHeaderClicked != headerClicked)
                {
                    _lastHeaderClicked.Column.HeaderTemplate = null;
                }


                _lastHeaderClicked = headerClicked;
                _lastDirection = direction;
            }
        }
    }


    private void Sort(string sortBy, ListSortDirection direction)
    {
        ICollectionView dataView =
          CollectionViewSource.GetDefaultView(lvPurchaseSummaryList.ItemsSource);

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

        dataView.SortDescriptions.Add(sd);
        dataView.Refresh();
    }
}

And this is from main window with some example in it...

    public ObservableCollection<PurchaseSummary> purchaseSummaryCol { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        purchaseSummaryCol = new ObservableCollection<PurchaseSummary>();
        purchaseSummaryCol.Add(new PurchaseSummary("100", "basd", "asd", "basd", "asd", "basd", "asd", "basd", "asd", new Pay(DateTime.Today, DateTime.Today, 3), new PayRestrict(), new Vod()));
        purchaseSummaryCol.Add(new PurchaseSummary("105", "asd", "basd", "asd", "basd", "asd", "basd", "asd", "basd", new Pay(DateTime.Today, DateTime.Today, 3), new PayRestrict(), new Vod()));
        purchaseSummaryCol.Add(new PurchaseSummary("101", "casd", "cbasd", "casd", "cbasd", "casd", "cbasd", "casd", "cbasd", new Pay(DateTime.Today, DateTime.Today, 3), new PayRestrict(), new Vod()));

        PurchaseSummaryPage purchaseSummaryPage = new PurchaseSummaryPage();
        purchaseSummaryPage.DataContext = this;
        AttachPageToFrame(_f, purchaseSummaryPage);
    }

1 Answers1

1

The cause is from this code :

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

which it uses header text which in your case it's not the same with Property Name, simple way to fix is try set Header as the same with Property Name Header="originalName"

For better solution, you can store the propertyName need to sort in Tag of Header, but we need to do more like this:

 <GridViewColumn Width="100"  DisplayMemberBinding="{Binding Path=originalName}"  >
                    <GridViewColumn.Header>
                        <TextBlock Text="Original Name" Tag="originalName"/>
                    </GridViewColumn.Header>
                </GridViewColumn>

then in code:

 GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
        var tb = headerClicked.Column.Header as TextBlock;
        var propertyName = tb.Tag as string;
        Sort(propertyName, direction);
nhabuiduc
  • 998
  • 7
  • 8