Hi,
I have a use case which is explained as follows:
"I have a UltragGrid which has some 10 column. But I need two types of sorts for these columns. i.e Some columns need default sorting provided by UltraGrid, and some other columns requires Three Way Sorting."
Three Way Sorting in my point of view is:
a. Ascendiing -Indicated by default ascending SortIndicator.
b. Descending- Indicated by default descending SortIndicator.
c. Absolute Descending: shoudl be indicated by a + sign.
I am new to the Infragistics. Can anyone help me in getting this with a nice example.
Thanks very much in advance.
Sanjeev.
Hi Sanjeev,
I think what you will have to do is trap the BeforeSortChange event and trap for when the column goes from no sorting to some sorting. Then you can cancel the event and set the SortIndicator to whatever you want, and also set up your CreationFilter and SortComparer to do that it needs to do to sort AbsoluteDescending.
Hi Mike,
Yes you are right, I had already implemented Three Way sorting. But the problem here is I need to get AbsoluteDescending order for the first time I click on the column header.
Instead I am getting descending order first then followed by AbsoluteDescening order.
Is there a way to get Absolute descending order first with out either ascending or descending.I know that by default it will be set to ascending and a there is another way to set descending order first as well. But I didn't find any way to set our own sort for the first time.
Thanks,
I'm still not sure what you are asking. The code you posted here seems to already be handling the 3-way sorting.
Of course, it's impossible to tell from a code snippet like this whether this is actually working correctly or not - especially such a long code snippet.
If it's not working, then what exactly is the problem? What part of this is giving you trouble?
I have requirement as follows:
1. I have two different types columns based on sorting. Three way sorting columns, and normal sorting columns.
Three way sorting columns: Absolute descending(+ Custom Icon), descending and ascending order.
Normal sorting columns: Descending and ascending.
2. Sortindicator should be displayed on left hand side of the columns.
3. Sorting order should be for
a. normal columns: Descending and followed by ascending.
b. Three way sorting columns: Absolute descending and descending and ascending.
I have done all the tasks expect 3 b. Where I am getting descending order first followed by absolute descending and ascending order.
Please have a look at the code(Removed some piece of code) and suggest me how should I get this done. Please let me know if didn't understand the requirement.
namespace Test{ public partial class GridPanel : UltraGridBagLayoutPanel { /// <summary> /// An enum which represents the different states of /// three way sorting /// </summary> public enum SORT_STATE { NONE = 0, ASCENDING, DESCENDING, CUSTOM }; #region Static Variables /// <summary> /// Represents the last cached state of a three way sort /// </summary> private static SORT_STATE mySortState; private delegate void SortColumnDescendingDelegate(UltraGridColumn column); #endregion #region Member Variables private GridDataModel myGridModel; private string myLastSortedColumn = null; private List<string> myThreeWaySortColumns; private Map<String, ColumnInfo> myColumnNameToColumnInfoMap; private Map<ColumnInfo, UltraGridColumn> myColumnInfoToGridColumnMap; private UltraGridColumn myFilterColumn = null; #endregion #region Internal classes /// <summary> /// Implements the sort specific to the sort state /// </summary> private class GridSortComparer : IComparer { /// <summary> /// CTOR /// </summary> internal GridSortComparer() { } int IComparer.Compare(object x, object y) { UltraGridCell xCell = (UltraGridCell) x; UltraGridCell yCell = (UltraGridCell) y; double text1 = Convert.ToDouble(xCell.Value.ToString()); double text2 = Convert.ToDouble(yCell.Value.ToString()); if (mySortState == SORT_STATE.CUSTOM) { text1 = Math.Abs(text1); text2 = Math.Abs(text2); if (text2 < text1) { return -1; } else if (text2 > text1) { return 1; } return 0; } if (text1 > text2) { return 1; } else if (text1 < text2) { return -1; } else { return 0; } } } /// <summary> /// Draws the SortIndicator icon to the left of the column name /// </summary> public class SortIndicatorOnLeftCreationFilter : IUIElementCreationFilter { #region IUIElementCreationFilter Members void IUIElementCreationFilter.AfterCreateChildElements(UIElement parent) { HeaderUIElement headerUIElement = parent as HeaderUIElement; if (headerUIElement != null) { SortIndicatorUIElement sortIndicatorUIElement = headerUIElement.GetDescendant(typeof(SortIndicatorUIElement)) as SortIndicatorUIElement; if (sortIndicatorUIElement != null) { // // Change the location of the sortIndicatorUIElement so that it's // on the left side of the headerUIElement. // sortIndicatorUIElement.Rect = new Rectangle( headerUIElement.RectInsideBorders.Left, sortIndicatorUIElement.Rect.Top, sortIndicatorUIElement.Rect.Width, sortIndicatorUIElement.Rect.Height); TextUIElement textUIElement = headerUIElement.GetDescendant(typeof(TextUIElement)) as TextUIElement; if (textUIElement != null) { // // Move The TextUIelement to the right of the sortIndicatorUIElement. // textUIElement.Rect = new Rectangle( sortIndicatorUIElement.Rect.Right, textUIElement.Rect.Top, textUIElement.Rect.Width, textUIElement.Rect.Height); } } } } bool IUIElementCreationFilter.BeforeCreateChildElements(UIElement parent) { // Do nothing. return false; } #endregion } /// <summary> /// Used a DrawFilter for table to draw /// a + Icon for absolute sort /// </summary> public class AbsoluteSortIndicatorDrawFilter : IUIElementDrawFilter { private GridPanel myGridPanel; /// <summary> /// CTOR /// </summary> public AbsoluteSortIndicatorDrawFilter(GridPanel gridPanel) { myGridPanel = gridPanel; } #region IUIElementDrawFilter Members bool IUIElementDrawFilter.DrawElement(DrawPhase drawPhase, ref UIElementDrawParams drawParams) { if (drawPhase == DrawPhase.AfterDrawElement) { HeaderUIElement headerUIElement = drawParams.Element as HeaderUIElement; if (headerUIElement != null) { UltraGridColumn column = drawParams.Element.GetContext(typeof(UltraGridColumn)) as UltraGridColumn; // // If it is not a threey way sort column // if (!(myGridPanel.IsThreeWaySortColumn(column.Key))) { return false; } if (mySortState == SORT_STATE.CUSTOM) { column.SortIndicator = SortIndicator.None; Rectangle rect = headerUIElement.Rect; rect.Inflate(+1, -1); rect.Offset(-2, 0); // // Creating a new rectangle // with some size to draw this icon // Rectangle newRect = new Rectangle( new Point(headerUIElement.Rect.Left, (rect.Y + rect.Height / 3)), new Size((rect.Width / 2 + rect.Width / 4), (rect.Height / 2 + rect.Height / 4))); ImageAttributes imageAttr = new ImageAttributes(); ColorMap[] colorMap = new ColorMap[1]; colorMap[0] = new ColorMap(); colorMap[0].OldColor = Color.White; colorMap[0].NewColor = Color.White; imageAttr.SetRemapTable(colorMap); System.Resources.ResourceManager RM = new System.Resources.ResourceManager("UI.Resources", GetType().Assembly); Object obj = RM.GetObject("plusIcon"); using (Bitmap bmp = (Bitmap) obj) { drawParams.Graphics.DrawImage( bmp, newRect, 0, 0, newRect.Width, newRect.Height, GraphicsUnit.Pixel, imageAttr ); } return true; } } } return false; } DrawPhase IUIElementDrawFilter.GetPhasesToFilter(ref UIElementDrawParams drawParams) { if (drawParams.Element is HeaderUIElement) { // // Get the column. // UltraGridColumn column = drawParams.Element.GetContext(typeof(UltraGridColumn)) as UltraGridColumn; if (!myGridPanel.IsThreeWaySortColumn(column.Key) || myGridPanel.myLastSortedColumn == null || !myGridPanel.myLastSortedColumn.Equals(column.Key)) { return DrawPhase.None; } return DrawPhase.AfterDrawElement; } return DrawPhase.None; } #endregion } #endregion /// <summary> /// CTOR /// </summary> public GridPanel() : base(TITLE) { Initializae(); } private void Initialize() { myThreeWaySortColumns = new List<string>(); InitializeComponent(); myGridModel = new PositionDataModel(); this.myUltraGrid.DataSource = myGridModel; this.myUltraGrid.BeforeSortChange += new BeforeSortChangeEventHandler(HandleBeforeSortChange); this.myUltraGrid.CreationFilter = new SortIndicatorOnLeftCreationFilter(); } #region Public Methods /// <summary> /// Handles this event to set descending order first /// </summary> private void HandleBeforeSortChange(object sender, BeforeSortChangeEventArgs e) { if (e.SortedColumns.Count == 0) { return; } UltraGridColumn sortetColumn = e.SortedColumns[0]; if (myLastSortedColumn == null || !myLastSortedColumn.Equals(sortetColumn.Key)) { myLastSortedColumn = sortetColumn.Key; mySortState = SORT_STATE.NONE; } if (IsThreeWaySortColumn(e.SortedColumns[0].Key)) { SortIndicator indicator = sortetColumn.SortIndicator; if (mySortState == SORT_STATE.NONE) { mySortState = SORT_STATE.CUSTOM; } else if (mySortState == SORT_STATE.CUSTOM) { mySortState = SORT_STATE.DESCENDING; } else if (mySortState == SORT_STATE.DESCENDING) { mySortState = SORT_STATE.ASCENDING; } else if (mySortState == SORT_STATE.ASCENDING) { mySortState = SORT_STATE.CUSTOM; } } // // Iterate through the new SortedColumns and see if there is a new column in there // that did not exist in the original sorted columns. This will tell us if a // column is being sorted for the first time. // foreach (UltraGridColumn column in e.SortedColumns) { if (e.Band.SortedColumns.Exists(column.Key) == false) { // // We found a new column. Cancel the change. // e.Cancel = true; // // Now we want to sort the column descending. But we cannot change the // SortedColumns collection inside this event. So we will do it // by invoking another method. // this.BeginInvoke( new SortColumnDescendingDelegate( this.SortColumnDescending), new object[] { e.Band.Columns[column.Key] }); } } } /// <summary> /// This will clear old sort apply new sort /// </summary> private void SortColumnDescending(UltraGridColumn column) { // // Disable the BeforeSortChange event to avoid recursion. // this.myUltraGrid.EventManager.SetEnabled(GridEventIds.BeforeSortChange, false); try { // // Sort the specific column descending. // column.Band.SortedColumns.Clear(); column.Band.SortedColumns.Add(column, true); } finally { // //Re-enabled the BeforeSortChange event. // this.myUltraGrid.EventManager.SetEnabled(GridEventIds.BeforeSortChange, true); } } #endregion private bool IsThreeWaySortColumn(string columnName) { return myThreeWaySortColumns.Contains(columnName); } #endregion }}
Sanjeev
I'm not sure I understand your question.
The SortComparer only gets called if the SortIndicator on the column is Ascending or Descending. So you need to set the SortIndicator to Descending regardless of whether you want Descending or Absolute Descending (or whatever custom order you want).
You will need to keep track of what kind of sorting you want and then sort accordingly with some member variable or your own, whether that be on the column or the SortComparer or wherever. So to programmatically set the sort order to you would set the SortIndicator and then also set whatever member variable that you are using and then you may have to call band.SortedColumns.Refresh to tell the grid to re-sort, since the SortIndicator may not have changed.