mono / xwt

A cross-platform UI toolkit for creating desktop applications with .NET and Mono
MIT License
1.37k stars 241 forks source link

WPF ListView sort does not work #476

Open steffenWi opened 9 years ago

steffenWi commented 9 years ago

Hi,

sorting a ListView does not work on WPF. I can click the column header but nothing else is happening. This is also true for the sample application.

I do not seem to be able to add this functionality.

Based on some samples I found, I modified the ListViewBackend.cs:

  public object AddColumn(ListViewColumn col)
        {
            var column = new GridViewColumn();
            column.CellTemplate = new DataTemplate { VisualTree = CellUtil.CreateBoundColumnTemplate(Context, Frontend, col.Views) };
            if (col.HeaderView != null)
                column.HeaderTemplate = new DataTemplate { VisualTree = CellUtil.CreateBoundCellRenderer(Context, Frontend, col.HeaderView) };
            else
                column.Header = new GridViewColumnHeader() { Content = col.Title, Tag = col.Title };

            (column.Header as GridViewColumnHeader).Click += ListViewBackend_Click;
            this.view.Columns.Add(column);

            return column;
        }

        private void ListViewBackend_Click(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader column = (sender as GridViewColumnHeader);
            ListSortDirection dir = ListSortDirection.Ascending;

            // if there is a binding, use it
            // if there is no binding, check if the tag is of any use
            // if the tag is of no use there is nothing we can do -> sorting is impossible
            Binding b = column.Column.DisplayMemberBinding as Binding;
            string propName = string.Empty;
            if (b != null)
            {
                propName = b.Path.Path;
            }
            else if (this.ListView.Items.Count > 0 && this.ListView.Items[0].GetType().GetProperties().Where(x => x.Name == column.Tag.ToString()).Count() > 0)
            {
                propName = column.Tag.ToString();
            }
            else
            {
                return;
            }

            var adornerLayer = AdornerLayer.GetAdornerLayer(column);
            try { adornerLayer.Remove((adornerLayer.GetAdorners(column))[0]); }
            catch { }
            if (this.ListView.Items.SortDescriptions.Count > 0 && this.ListView.Items.SortDescriptions.Where(x => x.PropertyName == propName).Count() > 0)
            {
                var sortDesc = this.ListView.Items.SortDescriptions.Where(x => x.PropertyName == propName).First();
                this.ListView.Items.SortDescriptions.Remove(sortDesc);
                if (sortDesc.Direction == ListSortDirection.Ascending)
                {
                    dir = ListSortDirection.Descending; // toggle
                }
                else
                {
                    return; // and reset                    
                }
            }

            var sortingAdorner = new SortingAdorner(column, dir);
            AdornerLayer.GetAdornerLayer(column).Add(sortingAdorner);
            this.ListView.Items.SortDescriptions.Add(new SortDescription(propName, dir));
        }

but apparently the way data is added there is no binding.

sevoku commented 9 years ago

I have not enogh knowledge about Wpf and sorting atm. I think @riviti has done something similar for TreeViews in #243 (Wpf part in 05322070c97c5f3bfd462aa860503785ee030ea1). But he didn't use the Header sorting features (see my comment https://github.com/mono/xwt/pull/243#discussion_r23135167). Maybe you can find something useful about the binding.