private void SetSorting(GridViewColumnHeader columnHeader, ListSortDirection?sortingDirection = null)
        {
            if (!this.IsSortable)
            {
                return;
            }

            var path = GridViewColumnProperties.GetSortingPropertyName(columnHeader);

            if (path == null)
            {
                return;
            }

            var gridView = columnHeader.Column.GetInheritanceContext() as GridView;

            if (gridView == null)
            {
                return;
            }

            var listView = gridView.GetInheritanceContext() as ListView;

            if (listView == null)
            {
                return;
            }

            if (this.sortedHeader != null)
            {
                AdornerLayer.GetAdornerLayer(this.sortedHeader).Remove(this.sortAdorner);
                listView.Items.SortDescriptions.Clear();
            }

            var newSorting = sortingDirection ?? ListSortDirection.Ascending;

            if (!sortingDirection.HasValue && this.sortedHeader == columnHeader && this.sortAdorner.Direction == newSorting)
            {
                newSorting = ListSortDirection.Descending;
            }

            this.sortedHeader = columnHeader;

            this.sortAdorner = new SortAdorner(this.sortedHeader, newSorting)
            {
                Foreground = this.InheritanceContext.As <ListView>()?.Foreground
            };
            AdornerLayer.GetAdornerLayer(this.sortedHeader).Add(this.sortAdorner);

            try
            {
                listView.Items.SortDescriptions.Add(new SortDescription(path, newSorting));
            }
            catch (Exception e)
            {
                Debug.WriteLine("Error: Unable to sort elements: " + e.Message);
            }
        }
        private void CreateHeaders()
        {
            int index           = 0;
            var dataContextType = this.InheritanceContext?.As <FrameworkElement>()?.DataContext?.GetType();

            foreach (var column in this.AssociatedObject.Columns)
            {
                // check the header if it contains a GridViewColumnHeader or not... if not, then
                // create a GridViewColumnHeader and assign the value to the GridViewColumnHeader
                var header = column.Header is GridViewColumnHeader ?
                             column.Header as GridViewColumnHeader :
                             new GridViewColumnHeader {
                    Content = column.Header
                };

                header.Click += (s, args) => this.SetSorting(s as GridViewColumnHeader);
                header.Uid    = $"index_{index++}";
                header.HorizontalContentAlignment = HorizontalAlignment.Center;
                column.Header = header;

                if (dataContextType == null)
                {
                    continue;
                }

                var memberBinding = column.DisplayMemberBinding as Binding;
                if (memberBinding == null)
                {
                    continue;
                }

                var path = memberBinding.Path.Path;
                if (path == null)
                {
                    continue;
                }

                GridViewColumnProperties.SetSortingPropertyName(header, path);

                column.DisplayMemberBinding = null; // Always remove the displaybinding if a member is defined

                if (column.CellTemplate != null)
                {
                    continue;
                }

                // auto formatting down here
                var formatting = GridViewColumnProperties.GetFormatting(column);
                column.CellTemplate = this.CreateDateTemplate(memberBinding, formatting);
            }
        }