Question

how can i have a ultragrid with 3-way sorting on every columns? I mean :

a. Ascendiing -Indicated by default ascending SortIndicator.

b. Descending- Indicated by default descending SortIndicator.

c. No Sort- UnSort the column.

Note: I have tried BeforeSortChanged Event but i had 2 problems:

  1. I could not get the previous column sort indicator to find out when should i disable sorting.

  2. I have got an Exception where it is saying that we can't change SortIndicator in BeforeSortChange Event

Was it helpful?

Solution 2

I solved my problem by using UIElement.GetContext() to find clicked column in Mouse Up event handler of my grid and then i checked and changed the sortIndicator property of that column to what i want.

Edit :

private void Grid_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        UIElement element = Grid.DisplayLayout.UIElement.ElementFromPoint(new Point(e.X, e.Y));
        if (element == null)
            return;

        ColumnHeader clickedHeader = (ColumnHeader)element.GetContext(typeof(ColumnHeader), true);

        UltraGridColumn clickedColumn;

        if (clickedHeader != null)
            clickedColumn = clickedHeader.Column;

        if (clickedColumn == null)
            return;

        Switch ( clickedColumn.SortIndicator)
        {
           case SortIndicator.Ascending :
               clickedColumn.SortIndicator= SortIndicator.Descending;
               break;
           case SortIndicator.Descending :
               clickedColumn.SortIndicator= SortIndicator.Disabled;
               break;
           case SortIndicator.Disabled :
           default :
               clickedColumn.SortIndicator= SortIndicator.Ascending;
               break;
        }
    }
}

OTHER TIPS

It's not that trivial to implement the "unsorted" state. Once the data has been sorted, it is simply reordered within the band. You can see for yourself by applying the below code:

    Infragistics.Win.UltraWinGrid.UltraGridColumn[] oldSort;

    private void Sort() {
        ultraGrid1.BeforeSortChange += new Infragistics.Win.UltraWinGrid.BeforeSortChangeEventHandler(ultraGrid1_BeforeSortChange);
        ultraGrid1.AfterSortChange += new Infragistics.Win.UltraWinGrid.BandEventHandler(ultraGrid1_AfterSortChange);
    }

    void ultraGrid1_BeforeSortChange(object sender, Infragistics.Win.UltraWinGrid.BeforeSortChangeEventArgs e) {
        oldSort = new Infragistics.Win.UltraWinGrid.UltraGridColumn[e.Band.SortedColumns.Count];
        e.Band.SortedColumns.CopyTo(oldSort, 0);
    }

    void ultraGrid1_AfterSortChange(object sender, Infragistics.Win.UltraWinGrid.BandEventArgs e) {
        for (int i = 0; i < oldSort.Length; i++) {
            for (int j = 0; j < e.Band.SortedColumns.Count; j++) {
                Infragistics.Win.UltraWinGrid.UltraGridColumn column = e.Band.SortedColumns[j];
                if (column.Key == oldSort[i].Key) {
                    if (column.SortIndicator == Infragistics.Win.UltraWinGrid.SortIndicator.Ascending) {
                        //column.SortIndicator = Infragistics.Win.UltraWinGrid.SortIndicator.None;
                        e.Band.SortedColumns.Remove(column.Key);
                        j--;
                        break;
                    }
                }
            }
        }
    }

My guess is that you would need to keep a separate array with the row indices in it, and reorder rows within a band once the sorting is removed, according to the array. But that could be memory consuming in my opinion.

Another approach would be to have an additional hidden column, which could be filled with integers incremented in a simple for loop. Once the column's sort is "removed", you simply apply the Ascending sort to that hidden column. There are other aspects that needs to be maintained with such method though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top