Home - Forums-.NET - FlyGrid.Net (Windows Forms) - Invalidation bug still not fixed in 1.4.0.5

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

Invalidation bug still not fixed in 1.4.0.5
Link Posted: 09-May-2006 21:04
Hi,

unfortunately the invalidation bug that I was writing to you about for months now and have found the root of it in your source code and pointed you to where the problem exactly is, still hasn't been fixed in the latest version? Why not?

Tom
Link Posted: 10-May-2006 06:07
Seems that you've not received my mail.
Try to understand here:
The problem you mentioned in that you've not correctly understand visiblity of columns and layers:
1. to find column (what might be invisible), use
2. to check visiblity of column use Column.Visible or existance of column in Columns.VisibleColumns array.
3. Columns.GetColumnFromCellIndex(index) is more safe analoque of Columns.VisibleColumns[index]
4. GetFieldNameFromCellIndex is more safe analogue of
Column col =  VisibleColumns[cellIndex];
return col.FieldName;

I've noticed that you're using column cache to change cell values, but why you do not use direct ways: Column.SeCellValue(Node) or Node.SetValue(Column)?
You can use more faster way if will use following way:

//here is my vision of your problem solution,
//context of methods below - control derived from FlyGrid
//without invalidation
private void ChangeCellValue(Node node, Column col, object value)
{
  ChangeCellValue(node, col, value, false);
}

//with/without invalidation
private void ChangeCellValue(Node node, Column col, object value, bool invalidate)
{
  //this is a index to place data into internal data representation
  // - directly to node.Value that containing array of data to display in cells
  // as some columns can't be visible, direct way uses columns map to
  //create own map that points to internal data
  int cellIndex = GetColumnIndexForCellValues(col);
  if (cellIndex != -1)
  {
    object[] cellValues = node.Value as object[];
    cellValues[cellIndex] = value;
    if (invalidate)
      this.ActiveRootPort.InvalidateCell(node, col);
  }
}

private int GetColumnIndexForCellValues(Column col)
{
  return Array.IndexOf(ColumnCache, col);    
}

private Column[] columnCache = null;
internal Column[] ColumnCache
{
  get
  {
    if (columnCache == null)
      BuildColumnCache();
    return columnCache;
  }
}

//this method you can use when rebuild columns - restructure data in the //grid or change layout (not when columns reodered, become invisible or hidden)
public void ResetColumnCache()
{
  columnCache = null;
}
private void BuildColumnCache()
{
   ArrayList map = this.Columns.GetColumnMap();
   columnCache = new Column[map.Count];
   for(int i=0; i < columnCache.Length; i++)
   {
      ColumnFieldTag cft = map[i] as ColumnFieldTag;
      columnCache[i] = cft.Column;
   }
}
Link Posted: 10-May-2006 06:35
Hi,

thanks for the reply. I didn't receive your email.

Here's my issue though:
My column cache holds the column index. So ColumnCache[\"col1\"] might return 0 for example. I see your point in having the ColumnCache hold the column itself rather than the column index, however I still think that the behavior here is a bug:
If column 0 is hidden and column 1 is visible and I try to set node[1] = 1; It tries to invalidate VisibleColumn with index 1 which doesn't exist, so you don't see the value updated in the cell. I can send you a code sample that proves this if you want.

I'm not using Column.SeCellValue(Node) or Node.SetValue(Column) because you said node[index] = value is the fastest way and speed is of utter importance here
Link Posted: 10-May-2006 08:19

My column cache holds the column index. So ColumnCache[\"col1\"] might return 0 for example. I see your point in having the ColumnCache hold the column itself rather than the column index, however I still think that the behavior here is a bug:
If column 0 is hidden and column 1 is visible and I try to set node[1] = 1; It tries to invalidate VisibleColumn with index 1 which doesn't exist, so you don't see the value updated in the cell. I can send you a code sample that proves this if you want.

Try to use more simple and clear scheme to work with columns cache from my sample or use node[Column] to set cell values.


I'm not using Column.SeCellValue(Node) or Node.SetValue(Column) because you said node[index] = value is the fastest way and speed is of utter importance here

But I didn't know that you hide/show some columns.
Yes you can use node[index] to set cell value directly to internal data representation, but you should correctly specify index.
You can use code in my previous post and replace ChangeCellValue with following:

private void ChangeCellValue(Node node, Column col, object value)
{
  int cellIndex = GetColumnIndexForCellValues(col);
  if (cellIndex != -1)
  {
     node[cellIndex] = value;
  }
}
Link Posted: 10-May-2006 10:47
Well, the point I'm trying to make is that node[index] = value should always invalidate the same cell no matter if there's a hidden column or not.
(btw. can you please address the other open questions in the board as well?)
Link Posted: 10-May-2006 11:36
see this sample ... you can't tell me that this is expected behavior:

    public partial class Form1 : Form
    {
        private FlyGrid grid;

        public Form1()
        {
            InitializeComponent();

            grid = new FlyGrid();
            grid.Dock = DockStyle.Fill;
            toolStripContainer1.ContentPanel.Controls.Add(grid);

            grid.Columns.Items.Add(new Column(\"col1\"));
            grid.Columns.Items.Add(new Column(\"col2\"));
            grid.Columns.Items[\"col1\"].Visible = false;

            grid.Rows.Items.Add(new Node(new object[grid.Columns.Items.Count]));  
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            grid.Rows.Items[0][grid.Columns.Items[\"col2\"]] = 1;
        }
    }


So, when this is called: grid.Rows.Items[0][grid.Columns.Items[\"col2\"]] = 1;
... the cell is not invalidated and you don't see the value in the cell until you click on it

same goes for grid.Rows.Columns.Items[\"col2\"].SetValue(grid.Rows.Items[0], 1); for example...
Link Posted: 11-May-2006 02:01
This much help to find bug.
We've already fixed and improved cell changing.
Fixed version will available today.
Link Posted: 11-May-2006 11:39
thank you, invalidation is finally working correctly