How to sort ListView With ObservableCollection by Clicking Header

半腔热情 提交于 2019-12-12 06:15:23

问题


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:


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);


来源:https://stackoverflow.com/questions/30072961/how-to-sort-listview-with-observablecollection-by-clicking-header

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!