Subject: Accessing a cell in a DataGridView
Posted By: Martin Woodhouse Post Date: 4/16/2008 2:15:02 AM


This is so elementary that I am almost ashamed to ask it: but although I am an experienced programmer in plain old C, I am only just starting out with Visual C# and have nobody standing at my shoulder who could doubtless give me an answer in ten seconds.

I have "Visual C# Express Starter Kit" and "Beginning Visual C# 2005", through both of which, and the Help file, I have searched in vain for three days --- looking at DataSets, Classes, Tables, Collections, etc --- without finding the answer to this simple question:-

Given that I have a DataGridView on my screen, how do I access a particular cell in it, by column and row, in programming terms?

I need to take (int16) values out of a series of such cells and transfer them to (for instance) a array of integers upon which I shall then perform arithmetical operations, all of which I shall be writing directly in C code.

I am looking for an instruction such as

"Int i = [ ? ? ? ? ? ][row][column] ...."

--- (but how do I put a cell address, or something like it using a DataSet, or whatever, in place of the [ ? ? ? ? ?][row][column])?

How do I do this, please, before I go slightly demented?

Martin Woodhouse ( www.martin-woodhouse.co.uk )




Reply By: Martin Woodhouse Reply Date: 4/16/2008 5:04:46 AM
Hello All

--- may I, as an example of the kind of thing which baffles me as a (doubtless over-intelligent) beginner, offer this?

I have added a DataGridView to my Form1 and populated it, successfully, from an external Access database.    No problem, in fact I am pretty pleased with Visual C# so far.

I have, in the Properties window for this DataGridView, renamed it SF3priceGrid. (Perhaps you can guess that it's displaying daily prices for the Swiss Franc.)

Now, as a first shot at trying to access one of its cells programmatically, I write (as a kind of rough guess) the following C command:-

 int testcell = SF3priceGrid.Rows(10).Cells(4).Value;

Ok.  I click Build.  Immediately I get a (single) error which tells me that there's no such name as SF3priceGrid  "in this context."

----------------------------------------------------------
(I have to say I am, no fooling, deeply impressed
with both the code editor and the debugging facility here.)
----------------------------------------------------------

I go back to the Design view and right-click on the grid; sure enough, it is called "SF3priceGrid" --- with all the upper and lower-case characters correct, everything kosher.   

So the inexperienced programmer -- myself -- asks:
"Why does the compiler tell me there's no such name?"
  
I assume I'm somehow not referring to the Grid correctly; but where would I begin looking to find out why not?

Cheers,

Martin Woodhouse

Reply By: samjudson Reply Date: 4/16/2008 5:44:40 AM
It is likely to do with scope. Where are you writing the line you mention above? If its not in an event or method inside the actual form class then you'll need to refer somehow to the form as well.

In visual studio as soon as you start typing you should get a helpful list of available methods and variables pop up (its called Intellisense).

Also, I suspect you mean Rows[10], rather than Rows(10).

/- Sam Judson : Wrox Technical Editor -/
Reply By: Martin Woodhouse Reply Date: 4/16/2008 6:33:04 AM
Hello Sam (and thank you) ---

(a)  Yes, I did both mean, and write, Rows[10] !

(b)  Yes, I also notice that useful bit of the editor which offers you suggestions as to what to type next -- but it doesn't seem helpful in the particular instance of names for controls?

(c)  Since the procedure(s) I need to write are all called by pressing an "ok" button, I'm using the useful facility of double-clicking that button in Design View, whereupon I get taken to the point in the overall code which is 'inside the curly brackets' for the button.

------------------------------------------------------
Does this mean that the term "in this context"
quoted in the error report implies that the DataGridView
name SF3priceGrid isn't recognised inside the code
for this button?
------------------------------------------------------

If so, what do I need to do to get it recognised?  Or is there another name (or prefix, for instance) by which it would be recognised?

( The scope of recognition for objects, etc always drives me nuts in ordinary C, I admit.)

( Also, I'm delighted that C# seems to have got rid of pointers, another nutty-driving area -- though I can see I shall have to study C#'s substitute method rather carefully . . . )

Regards,

Martin Woodhouse

Reply By: Martin Woodhouse Reply Date: 4/16/2008 7:45:24 AM
Hi Sam (and all)

My overall question remains:

I want to assign the (integer) value in a particular cell in a DataGridView to an integer variable, so that I can use that value in a series of programmed --- that is, not merely 'visual' -- procedures written directly in C.

This assignation (it seems to me) will be of the very general form:
"int n = [specified row].[specified column]"
w.r.t. the DataGridView, whose name as
declared on Form1 is "SF3priceGrid".

This must surely be a fairly common task?

 What, exactly, must I write in the body of the code to achieve it (given that whatever I write is to be executed in response to a click on a button and hence, as an initial guess, will be written inside the code space allocated to that button's response)?

Cheers,

Martin Woodhouse


Reply By: samjudson Reply Date: 4/16/2008 7:55:34 AM
If the DataGridView is on the form, and the button is also on the form then it should work fine.

Try typing: "this." and see the list of properties that come up via Intellisense. Your data grid should be listed.

Also, make sure it was the Name property that you renamed, and not another property.

If that doesn't solve it then I'm at a loss.

/- Sam Judson : Wrox Technical Editor -/
Reply By: Martin Woodhouse Reply Date: 4/16/2008 12:17:10 PM
Hello Sam (and  all)

Ok, but the trouble is that after typing "this", IntelliSense offers me a choice of what looks like several hundred words or phrases I could be typing next . . .

---------------------------------

Manfully struggling on in ignorance and with the not-enormous help of the three-inch thickness of books I've bought to instruct me in the ways of Visual C#, I start to think that the value of (let's say) record 200 (the row) and "Close" (the column for the closing price of the Swiss Franc on Day 200) is held not in the DataGridView at all, but rather in the corresponding DataSet.

True?

But if so, my addressing problem remains.   If I bring up the window containing a list of data sources, I see a name, SF3priceGrid, which --- I now conclude --- is not the name of the DataGridView I have put on the screen, called but of its underlying DataSet?

So I write a chunk of code, thus:

private void runMidas_Click(object sender, EventArgs e)
        {
        int testcell = 0;
            
         if(Convert.ToInt16(Spreadtextbox.Text) > 1)

/* (this is just a signal showing that the user has actually picked a row from the DataGridView, and now wants to start the calculations involved in a (hefty) procedure called MIDAS . . . otherwise it might try to use values which haven't been assigned and thereby blow up in a big way . . .) */

            testcell = SF3DataSet.Tables["SF3"].Rows[200]["Close"];

/* Taken from p.787 in "Beginning Visual C# 2005" */

                 TestCelltext.Text = Convert.ToString(testcell);
         }      

-------

Okay?    Now I click Build.   I get the  following error report:

----------
Error    1    An object reference is required for the non-static field, method, or property 'MidasTest15.SF3DataSet.Tables.get'

-----------

Questions:

(A) Why is it telling me to use (or assuming that I am using)
    'MidasTest15.SF3DataSet.Tables.get'?    I presume that this is a method (or an object?) for getting at the value of a cell?   I can find no direct reference to  it, though?

(B) Is the line

testcell = SF3DataSet.Tables["SF3"].Rows[200]["Close"];

--- correct for addressing the cell in Row 200, column headed "Close", in the DataSet which belongs with the DataGridView which I have actually renamed "SF3priceGrid"?

Cheers,

(still ) Martin Woodhouse

Reply By: planoie Reply Date: 4/16/2008 1:07:20 PM
Martin,

The line for getting the column value looks correct to me.  However, not seeing the declarations for the various classes I can't see why you would be getting this error.  Can you post the code that declares the dataset?  You may need to look in the designer file for the form to find it.

-Peter
peterlanoie.blog
Reply By: Martin Woodhouse Reply Date: 4/16/2008 7:45:57 PM
Hi Peter

Thanks for replying.   Here's  the section of code (from form1.cs)which fills sF3DataSet.SF3   :-

----------------------------------------------------------
 private void Form1_Load(object sender, EventArgs e)
        {

            this.sF3TableAdapter.Fill(this.sF3DataSet.SF3);

        }
-----------------------------------------------------------

(which, I take it, fills the DataSet from the actual source, an outside Access database)?


-- and here is the code from the top of SF3DataSet.cs :-

-------------------------------------
namespace MidasTest15 {
    
      public partial class SF3DataSet {
        partial class SF3DataTable
        {
        }
    }
}
----------------------------------------

(I have copied/pasted the code in each case).

Cheers,

Martin




Reply By: Martin Woodhouse Reply Date: 4/16/2008 8:07:44 PM
. . . Incidentally, the fact that I am currently being driven mental by it doesn't imply any falling-off in my admiration for Visual C# as a programming tool.   For one thing, I'm 75 and I built my first computer in 1958 --  

see www.martin-woodhouse.co.uk

-- which means, half a century ago, and experience has therefore long since taught me that anything to do with The Wonderful World Of Computing has the built-in property of being able to drive a person crazy.

The ability to "auto-write" reams of code by dragging stuff onto and around a Form is terrific, though, and leaves one free to concentrate on writing the actual procedure one wants directly in C.

The snag, I can see, is that  the reams of code which get auto-written are sometimes more difficult to understand than if one had slogged through writing them oneself --- particularly in the case of trying to grasp what the Error Handler is saying . . . !

Cheers

Martin

Reply By: Martin Woodhouse Reply Date: 4/16/2008 8:34:27 PM
Hello All   (at 2.30 in the morning)

You see what being polite does for you?  Visual C#, recognising my recent compliment, has at last given me the right form for the code line I was looking for --- which is :

testcell = (int)this.sF3DataSet.Tables["SF3"].Rows[200]["Close"];

--- and has now compiled without error !

So there you go, eh?

Now all I have to do is index the record, or sixteen of them actually, instead of just setting '200' as a constant (remembering that the index starts at 0 and not 1, yeah?) and then transfer their fields into a local array of structures (don't let me even get started on that as a mental-driving topic) instead of into a single integer, and Bob's your uncle, eh?

Right.  Right.  Okay.   Bit of a sleep first, though, I think . . .


Cheers and regards to all,

Martin Woodhouse

Reply By: planoie Reply Date: 4/17/2008 9:30:50 PM
Martin,

Glad you got it worked out.  I checked out your site, very interesting stuff.  I like the idea of the Lightbook.

-Peter
peterlanoie.blog
Reply By: DrPurdum Reply Date: 10/3/2008 8:42:39 AM
I got here too late to be of help, but the cause of this problem is probably because of the difference between value types and reference types. Always remember: with reference types like a data grid, all you get is a memory address that points to where the data will be stored. That is, when you drag a data grid onto a form, in essence you are saying:

DataGridView myGrid;

This creates nothing but a 4-byte variable capable of holding a memory address that will ultimately point to the data in the grid. The current value of myGrid is null after the statement above. Your statement:

int testcell = SF3priceGrid.Rows(10).Cells(4).Value;

failed is because you are trying to make "Rows" a method call. As soon as Visual Studio saw the opening parenthesis after "Rows", it gave up because it couldn't find an object named SF3priceGrid with a method named Rows(). However, even if you had used brackets, as in:

int testcell = SF3priceGrid.Rows[10].Cells[4].Value;

that would still have failed because there are no row objects yet. The reason you got it to work is because you used data binding to actually create a data grid object in memory. Data binding has the effect of sending a memory allocation message to the Windows Memory Manager and creates a free memory block for the upcoming data. The memory address for this block is what gets assigned into myGrid, or SF3priceGrid in your example.

Dr. Purdum


Jack Purdum, Ph.D.
Author: Beginning C# 3.0: Introduction to Object Oriented Programming (and 14 other programming texts)

Go to topic 74366

Return to index page 1