Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » Best way to remove row from grid Collapse All
Subject Author Date
Offer Har Jan 14, 2009 - 10:52 AM

I have a grid with many rows. Each row has an ID, held in LPARAM of the first column’as cell in each row.


I need to remove a row from a given ID.


The trivial way would be to run over all rows, check the LPARAM and compare it to the ID i need to remove. The problem is that this approach is in O(N) whern N is number of rows.


Is there a more efficient way of doing this?


Thanks,


Ron.

Technical Support Jan 15, 2009 - 1:25 PM

We are sorry, you need to implement two data provider’s notification methods:

               virtual void OnDataProviderSwapSeries(
                                    bool bColumns, // true = sorting/swapping columns, false - rows
                                    LONG nRowColNo1,
                                    LONG nRowColNo2,
                                    LONG nSwapCounter
                                    ) = 0;
                        virtual void OnDataProviderSwapDroppedSeries(
                                    bool bColumns, // true = swapping columns, false - rows
                                    LONG nRowColNoSrc,
                                    LONG nRowColNoDropBefore
                                    ) = 0;
First is notifying about swapping during sorting. Second is notifying about swapping during drag-n-drop. Please do not ignore the bColumns parameter.

The row indices are zero based, but you should subtract total number of top and bottom rows from each row index. The CExtGridWnd class APIs provide independent row indexing spaces for top rows, bottom rows and data rows. But all the rows are stored inside one array of rows inside the data provider and this array contains all the top rows at the top of array, then all the bottom rows and then all the data rows.

Technical Support Jan 14, 2009 - 12:22 PM

Thank you for the interesting question. The solution you described will work but it’s not effective. You should use your own grid window class which has the map of row identifiers. This map should use the row identifier as key value and real row index as data value. The grid window should update the data values for each key stored in the map when the rows added, removed and sorted. You should implement the following methods for handling these events:

   virtual bool RowInsert(
                        LONG nRowNo, // -1 or greater than count - append
                        LONG nRowInsertCount = 1L,
                        bool bRedraw = true
                        );
            virtual LONG RowRemove(
                        LONG nRowNo,
                        LONG nRowRemoveCount = 1L, // -1 - remove up to end (truncate)
                        bool bRedraw = true
                        );
            virtual void OnDataProviderSwapDroppedSeries(
                        bool bColumns, // true = swapping columns, false - rows
                        LONG nRowColNoSrc,
                        LONG nRowColNoDropBefore
                        );

First two methods are provided by the CExtGridBaseWnd class. Third method is provided by the CExtGridDataProvider::IDataProviderEvents structure which is one of the bases of the CExtGridWnd class. This method is invoked during grid sorting. The CExtGridWnd class implements this method because it’s need to synchronize rectangular selection areas during sorting. As result, the grid cells which were selected before row/column sorting are still selected after sorting. This task is very similar to yours because it tracks the data which is linked to parti

So all the methods can be handled in your CExtGridWnd-derived class.


Offer Har Jan 14, 2009 - 8:39 PM

Another problem is that when I get to RowRemove, I need to run over all rows to adjust them, because all the row indexes are now invalid - correct me if I’m wrong...

Offer Har Jan 14, 2009 - 6:29 PM

Dear Support,


Thanks for the answer. I think there is one thing I don’t understand - How can I add an entry into the map in RowInsert? I don’t have the ID here, only the row number. I think I have to add the items into the map when I add rows ’manually’ - please explain if I missed anyhing...


About OnDataProviderSwapDroppedSeries tell if this is enough:



void CMyGrid::OnDataProviderSwapDroppedSeries(
    bool bColumns, // true = swapping columns, false - rows
    LONG nRowColNoSrc,
    LONG nRowColNoDropBefore
    )
{
    int nID1 = GridCellGet(m_nColWithID, nRowColNoSrc)->LParamGet();
    int nID2 = GridCellGet(m_nColWithID, nRowColNoDropBefore)->LParamGet();
    m_mapID2Row[nID1] = nRowColNoDropBefore;
    m_mapID2Row[nID2] = nRowColNoSrc;

    CExtGridWnd::OnDataProviderSwapDroppedSeries(bColumns, nRowColNoSrc, nRowColNoDropBefore);
}

Thanks,


Ron.

Offer Har Jan 14, 2009 - 6:41 PM

Another problem - I see that when I sort the grid, the function OnDataProviderSwapDroppedSeries is not called - any ideas?

Offer Har Jan 14, 2009 - 6:49 PM

OK, you specified the wrong function... I should use OnDataProviderSwapSeries.


But, I still have a problem - I have a 4 rows grid, and I get the number 4 in nRowColNo2, even though this is a 0 based index counting.


Any ideas?

Offer Har Jan 14, 2009 - 7:04 PM

Can it be that nRowColNo1 and nRowColNo2 are 1 based index?