Home - Forums-.NET - FlyGrid.Net (Windows Forms) - Sorting Problems 2

FlyGrid.Net (Windows Forms)

.NET Datagrid - Fast, highly customizable, industry standards .NET data grid control for WinForms

This forum related to following products: FlyGrid.Net

Sorting Problems 2
Link Posted: 23-Jun-2006 10:33
Hi,

I am currenlty evaluating the FlyGrid control and trying to develop one of my dialogs using evaluation version 1.4.0.25923. Depending on whether I am successfull or not I could recommend our company to buy a real license.

I am experiencing problems with sorting similar to the problems described here: http://www.9rays.net/forums/viewtopic.php?t=853

I have following questions:

1. Am I understanding right, that the FlyGrid CAN NOT sort rows in bound mode by default (no additional coding from my side, only with Columns.Options.ChangeSortOrderOnClick=true set in the designer) if the DataSource is an array, which implements an IList interface?
Is the custom sorting required in this case? Should I use my own IComparer implementation?

Here is how I am populating grid with data:

private void Form1_Load(object sender, System.EventArgs e)
{
  ArrayList list = new ArrayList();
    
  Data d1 = new Data(1, \"test1\" );
  Data d2 = new Data(2, \"test2\" );
  Data d3 = new Data(3, \"test3\" );
  Data d4 = new Data(4, \"test4\" );
  Data d5 = new Data(5, \"test5\" );

  list.Add( d1 );
  list.Add( d2 );
  list.Add( d3 );
  list.Add( d4 );
  list.Add( d5 );

  flyGrid1.Rows.DataSource = list;
}


2. In order to apply sorting in bound mode I tried to subscribe to grid's ColumnSortOrderChanging event, make my own IComparer interface implementation and to call flyGrid.Rows.Items.Sort(new MyIComparer()) in the ColumnSortOrderChanging event handler:


private void flyGrid1_ColumnSortOrderChanging(object sender, NineRays.Windows.Forms.Grids.Column column, System.Windows.Forms.SortOrder value, ref bool sorted)
{
    MyFlyGrid fg = sender as MyFlyGrid;

// I have tried every single from following commented lines:

//  fg.Rows.Items.Sort(new MyIComparer(column,value));
//  fg.Rows.Items.Sort(null);
//  fg.Rows.Items.Sort();
    fg.Rows.RefreshNodes();
    sorted = true;
}


I have also tried to override GetComparer() method of the FlyGrid class:

public class MyFlyGrid : FlyGrid
{
  public MyFlyGrid():base()
  {
  }
  protected override IComparer GetComparer(Rows rows, Column[] sortColumns)
  {
    return new MyComparer(sortColumns);
  }
}


Here is an IComparer implementation, which I have made following provided samples:

public class MyComparer : IComparer
{
  private SortOrder order;
  private Column col;
  private Column[] cols;

  public MyComparer(Column col, SortOrder order)
  {
    this.col = col;
    this.order = order;
  }

  public MyComparer(Column[] col)
  {
    this.cols = col;
    this.order = SortOrder.Descending;
  }

  #region IComparer Members

  public int Compare(object x, object y)
  {
    Node xnode = x as Node;
    Node ynode = y as Node;
    int result = 0 ;
    object xobj = xnode.GetCellValue(col);
    object yobj = ynode.GetCellValue(col);
    IComparable xvalue = xobj as IComparable;
    IComparable yvalue = yobj as IComparable;
    if (xvalue != null && order == SortOrder.Ascending)
    {
      result = xvalue.CompareTo(yvalue);
    }
    else if (yvalue != null && order == SortOrder.Descending)
    {
      result = yvalue.CompareTo(xvalue);
    }
    return result;
  }

  #endregion
}


I have also tried to make my data class implement IComparable interface.

But I did not succeed to sort my grid on column header click.
Actually, neither GetComparer() nor Compare() nor CompareTo() methods did not get called during execution in any of my attempts, although the ColumnSortOrderChanging event gets fired fine.

This is my sample data class:

public class Data : IComparable
{
  private string _ID;
  public string ID
  {
    get{ return _ID; }
    set{ _ID = value; }
  }

  private int _Value;
  public int Value
  {
    get{ return _Value; }
    set{ _Value = value; }
  }

  public Data(string id, int val)
  {
    _ID = id;
    _Value = val;
  }

  #region IComparable Members

  public int CompareTo(object obj)
  {
    Data d = obj as Data;
    if( d != null )
      return this.Value.CompareTo(d.Value);
    return 0;
  }

  #endregion
}



Could you please give me a hint, what am I doing wrong?

Thank you.
Link Posted: 23-Jun-2006 10:35
...during execution in any of my attempts, although the ColumnSortOrderChanging event gets fired fine.

This is my sample data class:

public class Data : IComparable
{
  private string _ID;
  public string ID
  {
    get{ return _ID; }
    set{ _ID = value; }
  }

  private int _Value;
  public int Value
  {
    get{ return _Value; }
    set{ _Value = value; }
  }

  public Data(string id, int val)
  {
    _ID = id;
    _Value = val;
  }

  #region IComparable Members

  public int CompareTo(object obj)
  {
    Data d = obj as Data;
    if( d != null )
      return this.Value.CompareTo(d.Value);
    return 0;
  }

  #endregion
}



Could you please give me a hint, what am I doing wrong?

Thank you.
Link Posted: 23-Jun-2006 11:03
When FlyGrid is working in databound mode and is sorting applied, FlyGrid tries to sort data through object provided as DataSource.
If you add your data to DataTable/DataView instead of ArrayList and bind to FlyGrid - in this case data will sorted with internal DataTable/DataView comparer.
If you add data directly, as following:
[c#]
private void Form1_Load(object sender, System.EventArgs e)
{
   //prepare data
   Data[] data = new Data[] {
         new Data(1, \"test1\" ),
         new Data(2, \"test2\" ),
         new Data(3, \"test3\" ),
         new Data(4, \"test4\" ),
         new Data(5, \"test5\" ),
      };
   //create nodes
   NodeBase nodes = new NodeBase[data.Length];
   //fill nodes
  for(int i=0; i < data.Length; i++)
  {
    nodes[i] = new Node(data[i]);
  }
  //add nodes
  flyGrid1.Rows.Items.AddRange(nodes);
}

in this case you can work with custom comparer.

PS: We'll improve FlyGrid.Net to recognize Array and ArrayList object and provide custom sorting in databound mode to the nearest update.
Link Posted: 23-Jun-2006 11:29
Also - relating to your scenario of data binding you can use following solution to custom sort data with current version of FlyGrid:
[c#]
private void flyGrid1_ColumnSortOrderChanging(object sender, NineRays.Windows.Forms.Grids.Column column, System.Windows.Forms.SortOrder value, ref bool sorted)
{
  MyFlyGrid fg = sender as MyFlyGrid;
  ArrayList al = fg.Rows.DataSource;
  if (al != null)//if data source is ArrayList
  {
    al.Sort(new MyIComparer(column,value));
    fg.Rows.RefreshNodes();
    sorted = true;
  }
}


Do not forget that in this case MyIComparer will sort Data objects not the nodes:
[c#]
public class MyIComparer : IComparer
{
  //....
  //....
  public int Compare(object x, object y)
  {
    Data dx = x as Data;
    Data dy = y as Data;
    //.....
    //...
  }
}
Link Posted: 24-Jun-2006 11:54
[quote="NineRays"]
If you add data directly, as following:
[c#]
private void Form1_Load(object sender, System.EventArgs e)
{
   //prepare data
   Data[] data = new Data[] {
         new Data(1, "test1" ),
         new Data(2, "test2" ),
         new Data(3, "test3" ),
         new Data(4, "test4" ),
         new Data(5, "test5" ),
      };
   //create nodes
   NodeBase nodes = new NodeBase[data.Length];
   //fill nodes
  for(int i=0; i < data.Length; i++)
  {
    nodes = new Node(data[i]);
  }
  //add nodes
  flyGrid1.Rows.Items.AddRange(nodes);
}

in this case you can work with custom comparer.


But this is not a bound mode anymore, isn't it?

[quote="NineRays"]
PS: We'll improve FlyGrid.Net to recognize Array and ArrayList object and provide custom sorting in databound mode to the nearest update.


That would be very good! That would be even greater, if the custom sorting via IComparable would be supported not only for Array and ArrayList data sources but also for any class, that implements IList (or even IEnumarable).

[i]Could you please say when such an update is expected to be available for download?


Thank you very much for a hint with ArrayList.Sort() sorting approach. It works! (Although, the data source in my real project is not an ArrayList and is a custom class, which implements IList).
Link Posted: 24-Jun-2006 23:29

That would be very good! That would be even greater, if the custom sorting via IComparable would be supported not only for Array and ArrayList data sources but also for any class, that implements IList (or even IEnumarable).

But not all IList/IEnumerable implementors support sorting.

Could you please say when such an update is expected to be available for download?

We plan to publish FlyGrid.Net with this feature today.

Thank you very much for a hint with ArrayList.Sort() sorting approach. It works! (Although, the data source in my real project is not an ArrayList and is a custom class, which implements IList).

Usually to support sorting, developers implementing IBindingList on data source objects, in this case FlyGrid.Net will interact with data source via this interface to sort data.
Link Posted: 25-Jun-2006 01:26
FlyGrid.Net update v1.4.0.14 is available for downloading.
Link Posted: 25-Jun-2006 10:31
[quote="NineRays"]

That would be very good! That would be even greater, if the custom sorting via IComparable would be supported not only for Array and ArrayList data sources but also for any class, that implements IList (or even IEnumarable).

But not all IList/IEnumerable implementors support sorting.

IMHO the grid should be able to sort the bound objects optionally using external IComparer implementations, something like client passing it's own IComparer implementaiton to the Rows.Sort() method, thus making it's usage similar to Array or ArrayList. Also, it would be nice to have a default grid's comparer settable from outside of the grid, probably even without a need to inherit from FlyGrid class (at least, it seems to be a very useful feature). The grid's sorting could also somehow make use of data object's IComparable implementations.

[quote="NineRays"]

Could you please say when such an update is expected to be available for download?

We plan to publish FlyGrid.Net with this feature today.

That's a great job! Thank you!

[quote="NineRays"]

Thank you very much for a hint with ArrayList.Sort() sorting approach. It works! (Although, the data source in my real project is not an ArrayList and is a custom class, which implements IList).

Usually to support sorting, developers implementing IBindingList on data source objects, in this case FlyGrid.Net will interact with data source via this interface to sort data.


Well, eventually IList was not my idea. Here what is written in the FlyGrid's documentation:

FlyGrid.Net supports data binding to data source objects such as IEnumerable, IListSource, DataTable, DataView, DataSet, and DataViewManager.

The following data sources are valid:
A DataTable
A DataView
A DataSet
A DataViewManager
A TreeCollection
Any component that implements the IListSource interface
Any component that implements the IEnumerable interface
Any component that implements the IList interface


IBindingList interface should be mentioned here or in Rows.Sort() method description section, otherwise it is not immediately clear, that the IBindingList implementation is required for sorting support in the databound mode.

Anyway, thank you very much!
Link Posted: 25-Jun-2006 11:53

Well, eventually IList was not my idea. Here what is written in the FlyGrid's documentation:

FlyGrid.Net supports data binding to data source objects such as IEnumerable, IListSource, DataTable, DataView, DataSet, and DataViewManager.

The following data sources are valid:
A DataTable
A DataView
A DataSet
A DataViewManager
A TreeCollection
Any component that implements the IListSource interface
Any component that implements the IEnumerable interface
Any component that implements the IList interface



Yes, but this sentence related to databinding. Some of IList implementors might not be sortable (for example, a collection that is optimized to be read in the order of inserts).


IBindingList interface should be mentioned here or in Rows.Sort() method description section, otherwise it is not immediately clear, that the IBindingList implementation is required for sorting support in the databound mode.

Thanks for suggestion, we'll correct our documentation to mention about IBindingList.