Skip to content

Turn Off Column Sort Indicator

New Discussion
David
David asked on Jul 29, 2011 2:55 PM

Hi,

I am looking for a way to turn off the display of the Sort Indicator on a sorted column while retaining the ability for the user to sort the column.

I have searched the forum and found a similar question – the suggested fix was to use a CreationFilter on the grid to cancel the creation of the SortIndicatorUIElement.

This does stop the indicator being displayed – however my problem is that the space is still made for the indicator anyway. How do I prevent this?

This results in wrapping of the header text unless I resize the column to fit the updated column header.

I have very strict (and unique!) requirements to save as much space as possible to resizing the column is not an option. I need to hide the indicator AND stop the grid reserving space for it also.

I have tried numerous workarounds involving resetting the columns SortIndicator property to None. This does the trick when sorting Ascending however when sorting Descending it reverts the sort to Ascending 🙁

Any suggestions are most welcome.

Thanks!

Sign In to post a reply

Replies

  • 0
    Mike Saltzman
    Mike Saltzman answered on Nov 3, 2008 3:39 PM

    Hi,

    One way you might be able to do this is to take advantage of the fact that when you set the SortIndicator on the column to None, the grid does not un-sort the column. So if you set the SortIndicator to Ascending, then force the grid to paint, you can then set the SortIndicator back to none to remove the indicator, while the column remains sorted. 

    Something like this:

            private void ultraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
            {
                e.Layout.Override.HeaderClickAction = HeaderClickAction.Select;
                e.Layout.Override.SelectTypeCol = SelectType.None;
            }

            private void ultraGrid1_MouseUp(object sender, MouseEventArgs e)
            {
                // Get the grid.
                UltraGrid grid = (UltraGrid)sender;

                // Get the last UIElement entered by the mouse.
                UIElement element = grid.DisplayLayout.UIElement.LastElementEntered;

                // Try to get a column header.
                Infragistics.Win.UltraWinGrid.ColumnHeader columnHeader = element.GetContext(typeof(Infragistics.Win.UltraWinGrid.ColumnHeader)) as Infragistics.Win.UltraWinGrid.ColumnHeader;
                if (columnHeader != null)
                {
                    // Get the last sort direction of the column from the tag property on the
                    // column header.
                    SortIndicator? sortIndicator = columnHeader.Tag as SortIndicator?;

                    // Toggle to sorting.
                    switch (sortIndicator)
                    {
                        case SortIndicator.Descending:
                        case null:
                            sortIndicator = SortIndicator.Ascending;
                            break;
                        case SortIndicator.Ascending:
                            sortIndicator = SortIndicator.Descending;
                            break;
                    }

                    // Store the new sort direction in the tag. This is so we can clear the
                    // SortIndicator property on the column, but still remember which direction
                    // the column was last sorted.
                    columnHeader.Tag = sortIndicator;

                    // Get the column.
                    UltraGridColumn column = columnHeader.Column;

                    // Force the grid to sort.
                    column.SortIndicator = (SortIndicator)sortIndicator;
                    column.Band.SortedColumns.RefreshSort(true);
                    column.Band.Layout.Grid.Refresh();

                    // Un-sort.
                    column.SortIndicator = SortIndicator.None;
                }
            }

    There are a couple of caveats, though.

    1) The grid sorts lazily. This means that in order to sort the grid, you will have to force it to paint while the SortIndicator is set. This is easy enough to do, but it means there will be a little flicked in the column header while the sort indicator appears and then disappears. To get around this, you can probably use the same CreationFilter you referred to here.

    2) Since the SortIndicator on the column is getting cleared, you will need to remember which columns are sorted and in what direction. In my sample code here, I use the Tag property on the column header. But my implementation here is incomplete. I did not, forexample, clear the tag of all of the other columns when you sort a column. I also didn't attempt to deal with multi-column sorting. 

    • 0
      David
      David answered on Nov 4, 2008 1:11 PM

      Thanks a lot Mike – that sounds like a great idea. I'll give it a try!

      • 0
        David
        David answered on Nov 14, 2008 11:08 AM

        Hi Mike

        I finally got time to try out your suggestion and unfotunately the “flicker” you mention when refreshing the grid to force it to sort is proving a problem. It is acting differently for different columns (perhaps based on the header text width or the column contents width) but I have tried a lot of variations in the Creation Filter (see code below) to try and move the sort indicator out of the way and remove it altogether but nothing seems to work – the problem remains that the grid seems to be trying to find somewhere to put the indicator.

        Any ideas would be very welcome. I am having trouble attaching an image from my machine showing the effect of the flicker but basically it shows one column’s header text bouncing right, one bouncing slightly left and one column header increasing in height. In call cases I think it’s trying to make space wherever it can for the sort indicator even though it has been removed. Below is  the code for my creation filter. Thanks in advance!

        public class RemoveSortIndicatorCreationFilter : IUIElementCreationFilter

         

        {

        private int sortIndicatorWidth = 0;

        private int sortIndicatorHeight = 0;

        #region IUIElementCreationFilter Memberspublic bool BeforeCreateChildElements(UIElement parent)

        {

        if ((parent.Parent is HeaderUIElement) && (parent is TextUIElement)) // HeaderUIElement) // SortIndicatorUIElement)

         

        {

        HeaderUIElement headerElement = parent.Parent as HeaderUIElement;

        // only play with the text element size if this column is sorted

        if (headerElement.Header.Column.SortIndicator != SortIndicator.None)

        {

        // Expand the text element to take account of the missing indicator

        foreach (UIElement element in parent.Parent.ChildElements)

        {

        TextUIElement descripElem = element as TextUIElement;if (descripElem != null)

        {

        Rectangle origRect = descripElem.RectInsideBorders;

        descripElem.Rect = new Rectangle(

        origRect.Left,

        origRect.Top,

        origRect.Width + this.sortIndicatorWidth,

        origRect.Height

        );

        break;

        }

        }

        }

        }

        else if (parent is SortIndicatorUIElement)

        {

        foreach (UIElement element in parent.Parent.ChildElements)

        {

        SortIndicatorUIElement descripElem = element as SortIndicatorUIElement;if (descripElem != null)

        {

        Rectangle origRect = descripElem.RectInsideBorders;

        this.sortIndicatorWidth = origRect.Width;

        this.sortIndicatorHeight = origRect.Height;

        descripElem.Rect = new Rectangle(

        origRect.Left,

        origRect.Top,

        0,

        0

        );

        break;

        }

        }

        // remove teh sort indicator element

         

        parent.Parent.ChildElements.Remove(parent);

        parent.Dispose();

        }

         

        // Return false so PositionChildElements will get called to do the default child element creation.

        return false;

        }

        public void AfterCreateChildElements(UIElement parent)

        {

        // nothing to do in this method

         

        }

         

        #endregion

         

        }

         

      • 0
        David
        David answered on Nov 14, 2008 11:58 AM

        Hi again

        Just an update – with the help of a sample I got from infragistics support I have worked out that the flicker I see is caused by 2 issues:

        1) My sort takes longer than the sample so the flicker is more noticable

        2) Most importantly, if I left-align the column header text there is no flicker noticed at all. However my columns are center-aligned and that seems to be a problem which causes the header text to shift left/right depending on the column

      • 0
        Mike Saltzman
        Mike Saltzman answered on Nov 14, 2008 3:36 PM

        Hm. I'm not sure why this isn't working. Your CreationFilter must be doing something differently when there is and is not a sort indicator. This CreationFilter also appears more complicated that I think it needs to be. 

        I tried this and it seems to work: 

            public class RemoveSortIndicatorCreationFilter : IUIElementCreationFilter
            {
                #region IUIElementCreationFilter Members

                public void AfterCreateChildElements(UIElement parent)
                {
                    if (parent is HeaderUIElement)
                    {
                        UIElement sortIndicatorUIElement = parent.GetDescendant(typeof(SortIndicatorUIElement));
                        if (sortIndicatorUIElement != null)
                        {
                            Rectangle rect = sortIndicatorUIElement.Rect;
                            UIElement textUIElement = parent.GetDescendant(typeof(TextUIElement)) as TextUIElement;
                            textUIElement.Rect = parent.RectInsideBorders;
                            parent.ChildElements.Remove(sortIndicatorUIElement);
                        }
                    }
                }

                public bool BeforeCreateChildElements(UIElement parent)
                {
                    return false;
                }

                #endregion
            }

         

        This assumes there's nothing but text in the column header (i.e. no images). 

      • 0
        David
        David answered on Nov 17, 2008 3:57 PM

        Hi Mike

        Thank you! Your better (and simpler) creation filter alone solves the problem. I do not even need the MouseUp code to artifically do the sorting. Setting HeaderClickAction on the grid to SortSingle and using your creation filter to hide the indicator does the job perfectly. I think my creation filter was trying to this the wrong way and failing to remove the space occupied by the sort indicator.

        Thanks again for all the help!

    • 0
      Robert
      Robert answered on Jan 29, 2009 10:00 PM

      Is there a way to always force the sort indicator to be ON for every column??

      I can set all the columns to Ascending on the Initialize_Layout. The problem is as I choose 1 column to sort the column to the left of my sorted column drops the sort indicator.

      • 0
        Mike Saltzman
        Mike Saltzman answered on Feb 2, 2009 3:52 PM

        Hm. I think you could try handling the BeforeSortChange event and then set the SortIndicator on every column.

      • 0
        Madhavi
        Madhavi answered on Jul 28, 2011 8:43 PM

        I would like to manually sort the Ultragrid.

        I'd like to remove the sorting from the Header Column. I am using the following to remove sorting

        e.Layout.Override.HeaderClickAction =

         

        HeaderClickAction.ExternalSortSingle;

        However, even if I call refreshSort() before binding the table to the grid,

        I am unable to sort the grid.

        Is there something that I am missing ?

         

        Thanks!

      • 0
        Mike Saltzman
        Mike Saltzman answered on Jul 29, 2011 2:55 PM

        Hi,

        I'm not sure I understand your question.

        HeaderClickAction.ExternalSortSingle means that the grid will display a Sort Indicator in the column header, but the grid will not actually sort the data.

        So if you are trying to remove sorting from the grid, you should be turning off sorting entirely by setting HeaderClickAction to None or Select.

        If you want to sort the data, then the best thing to do is to sort the data in your data source before you bind it to the grid. Or, if you are changing the sort order after the grid is bound, you need to tell the grid to refresh itself after the sort is complete.

        To refresh the grid, call:

        grid.Rows.Refresh(ReloadData);

         

  • You must be logged in to reply to this topic.
Discussion created by
Favorites
Replies
Created On
Last Post
Discussion created by
David
Favorites
0
Replies
10
Created On
Jul 29, 2011
Last Post
14 years, 7 months ago

Suggested Discussions

Created by

Created on

Jul 29, 2011 2:55 PM

Last activity on

Feb 25, 2026 9:25 AM