Link to home
Start Free TrialLog in
Avatar of Paulagier
PaulagierFlag for France

asked on

Loop not working

The datagridview is programmatically filled continuously ( 20 each sec) with rows by an external device.
I need to work on each new row added .
My idea is to monitor the nb of dgv rows with Count
Here comes the code :
private void ExtractLeftArmValue()
        {
            String searchValue = "337";
            int linefeeded = 1;
            int row = 0;
            string rowstring = row.ToString();
            string linestring = linefeeded.ToString();
          
            for (row = 0; row < dgvvNodes.Rows.Count -1 ; row++)
            {    
                
                if (dgvvNodes.Rows[row].Cells[0].Value.ToString().Equals(searchValue))
                {
                    string testdata = dgvvNodes.Rows[row].Cells[9].Value.ToString();
                    lbxElbowAngle.Items.Add(testdata);
                    linefeeded = linefeeded++;  
                } 
            }
        }

Open in new window


the loop does not work. I have only one line added thru the method "lbxElbowAngle.Items.Add(testdata);" whatever the number of lines added to the datagridview.
Avatar of Paweł
Paweł
Flag of Switzerland image

if you put a break point inside your ExtractLeftArmValue method, does it hit? if so if you put a break point inside your loop does it hit, just to make sure that your method is in fact being called?
Are you getting any error?
Avatar of Paulagier

ASKER

No error and the method is well fired.

Connecting the method to a button, each time the button is pressed, one line is treated
and the loop iterates over every row?

two things you can do right off the bat

for (row = 0; row < dgvvNodes.Rows.Count -1 ; row++) should be   for (row = 0; row < dgvvNodes.Rows.Count ; row++)
this is because the for loop will fire as long as row is less than count, once it's equal the loop will not fire

so if you have five items their indices will be 0 1 2 3 4, if you're saying loop while row < 5; meaning that if you subtract one you'll never iterate over the last row

linefeeded = linefeeded++;  should be  linefeeded++;
that's because  linefeeded++ compiles to linefeeded =  linefeeded+1;

however i don't think either of those two are your problem.

if (dgvvNodes.Rows[row].Cells[0].Value.ToString().Equals(searchValue))
I would bet your problem is in your if statement, I would think that when you call Value.ToString() you're not getting what you're expecting
You are right they are not the problem
Furthermore, changing Rows.Count -1 to Rows.Count raises an index out of range error
Really? index out of range, that's weird, what is "dgvvNodes"
a datagridview
sorry i got confused with the Count() function http://rextester.com/CHUUU88722

hmm so by getting the index out of range exception we know that you're iterating over every row, by adding at least one item to lbxElbowAngle we know that the if statement is working, what type is lbxElbowAngle
listbox
how are you populating your data for the datagridview, i suspect that the first cell isn't what you expect it to be or it isn't what it appears to be, as there maybe some leading or trailing whitespace. so " 337" or "337 "  and when you're comparing it to just "337" the comparison results in a false.
"337" is an ID number embedded in an external device that sends data thru WiFi to the PC.
Format is fine and cannot be change. The dgv displayed on screen looks fine as far as ID number and other data are concerned
So what you are doing. with the functionality, I mean functional requirement.?
ASKER CERTIFIED SOLUTION
Avatar of Paweł
Paweł
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
When, on a row added to the dgv, the condition " ID number =337"  is OK I need to import Cell[9] content in a listbox
To Pavel : the walk is already planned !! Unfortunately I have no landscape nearby similar to Jura mountains or lake :)
what is the type of the content in cell 9? maybe the ToString() function is overwritten to return an empty string, but that would be strange.

sorry to hear about the lack of landscape, I'm a bit further south, around lake geneva.
Windows / Web application ?

Send me the HTML for GridView and listbox controls ?
Avatar of sarabande
The datagridview is programmatically filled continuously ( 20 each sec) with rows by an external device.
 I need to work on each new row added .
 My idea is to monitor the nb of dgv rows with Count
if you fill the grid by an external device, it is  a good chance that this happened from a second thread. if so, you should show the code because gui elements like a grid may not be filled from outside but need a synchronized filling by the gui thread.

if you want to work only on new rows you either need two grids  or some kind of  a manager which tells what is new and what is old.

if count is not a grid property or was set by the worker thread handling the external device, it is a good chance that the value of Count was not actualized within the loop.  variables which could be updated by different threads msut be declared with the volatile keyword.

Sara
dgvvNodes (the datagridview) is filled thru a bindingsource object:
                 
vNodesBS.DataSource = wfCaptureManager.vNodes;
dgvvNodes.DataSource = vNodesBS;

Open in new window


My problem is without any doubt to identify  what is new and what is old.
is filled thru a bindingsource object:
that is not necessarily a guarantee that synchronisation is ok. are you sure that while you were in the loop neither rows were added to the grid nor removed? if not, you need to add synchronisation.

My problem is without any doubt to identify  what is new and what is old.

if the new rows were added at bottom line, it should not be very difficult to remember which rows already were processed and which are new. if not, you may add an extra column with a serial number or a timestamp. the column may be hidden and for internal use only.

Sara
synchronisation: rows are coming only thru the bindingsource

added while in the loop : yes, rows are added permanently at bottomline

" it should not be very difficult to remember which rows already were processed and which are new." I am sure that it is the case for you. But i am sure too that this is NOT the case for me (as a newbie) !!

Any idea of how to do that ? It will be of great help.
you do call the databind() method after you updated the datasource right

nvm you'r using winforms not webforms
I am only using windows forms.
does databind() exists in that context ??
no it does not
added while in the loop : yes, rows are added permanently at bottomline

if Count is not declared as volatile, Count will not be updated in the while condition even if hundred rows were added. that is because the compiler has not added code for to check the while condition every cycle.

if the bindingsource also deletes rows, things are worse as your code would access deleted rows (access violation).

in my opinion you definitively need exclusive access to the grid while you were running the loop. that could be done by a mutex, semaphore or critical section.

Any idea of how to do that ?
add a member variable 'int lastRowProcessed;' to your class and initialize it to -1.

whenever you process a row set the  lastRowProcessed to the row id of the last processed row. if the rows in the grid are never deleted, you simply could use the row number as row id. if the rows are both growing and shrinking, you should have a class for the data of one row. the class could have a unique row id as a member which you could use to remember which was the last row processed.

Sara
The member variable already exists ("linefeeded") and does not solve the problem you raise ("Count not working")
The volatile suggestion is great but neither in the "row" counter nor in the method this parameter is accepted ( Error      4      The modifier 'volatile' is not valid for this item)
I am wondering if  the best bet at that stage would not be to forget the idea of monitoring changes in the datagridview and build another binding to a more versatile object (List<T> ??)
It seems to me that dgv are not all built to easily handle programmatic changes of data?
Your opinion and any suggestion to do that ??
already exists ("linefeeded") and does not solve the problem you raise ("Count not working")
??? if you get exceptions while running the code you should try to find out why. exceptions are an indication of wrong coding and you can prevent them by correcting the code.

you should be able to define the volatile for int member variables. alternatively you could use a member function GridCount() which also is called for each loop cycle if you implement like

public int myclass::GridCount()
{
    //volatile int count = 0;   //defined in myclass or together with dgvNodes.
    count = dgvvNodes.Rows.Count;
    return count;
}

Open in new window


note, if you would run the loop in exclusive mode, you don't need the volatile because the Count would not change while you were processing/evaluating the rows.

Sara
The volatile keyword can only be applied to fields of a class or struct. local variables cannot be declared volatile.

see https://msdn.microsoft.com/en-us/library/x13ttww7.aspx for more Information.

Sara