DataGridView Null Reference Exception - c#

I have a webservice which populates my DataGridView using a couple of webmethods.
Without this code everything works great but I need the picture to change depending on the row selected and the name of the picture will be in a static column that will not change.
What I am trying to do is, in my webmethod, send it a picture name equal to picture1.jpg.
In the windows application I am using this code:
int i;
i = memdataGV.SelectedCells[0].RowIndex;
var pictext = memdataGV.Rows[i].Cells[5].Value.ToString();
pictureBox1.ImageLocation = "C:\\Pictures\\" + pictext;
When the DataGridView first populates everything works fine but when I click on one of my button events it throws an exception on the following line:
var pictext = memdataGV.Rows[i].Cells[5].Value.ToString();
NullReferenceException was unhandled
I tried to debug the code and I added the if statement to the top however does not seem to fix it.

Three possibilities:
i has an incorrect value (-1, for example)
Value at Cells[5] is NULL so when you call ToString() blows up.
Cells[5] does not exist. I.E. maybe it's another index, like 4, for example. The index is zero-based, remember.
Based on your comment, change your line to:
var pictext = memdataGV.Rows[i].Cells[5].Value==null?string.empty:memdataGV.Rows[i].Cells[5].V‌​alue.ToString();

Figured it out for some reason the index 5 was returning null and there was a value in the cell. So I did code to grab the value by the column name which found the value and is working
string pictext = Convert.ToString(selectedRow.Cells["PHOTOID"].Value)

Related

Getting a reference to a specific WPF listbox

I am trying to programmatically get a reference to a specific WPF listbox based on a string set to the name of the listbox. I am trying to finish off this bit of code:
StackTrace st = new StackTrace();
string cmn = (st.GetFrame(0).GetMethod().ToString().Remove(0, 5)).Remove(4, 3);
stringArray = processMethodName(cmn);
populateLists(stringArray[0], stringArray[1], lst_Ingredients);
My 'processMethodName' function returns a value for stringArray[2] which is set to 'lst_Ingredients' however I do not know how to implement it. Any suggestions?
Finally found an answer. Was frustrating due to the number of posts / links regarding refering to objects within a listbox. Anyway, here's the line of code that I needed:
populateLists(stringArray[0], stringArray[1], (ListBox)FindName(stringArray[2]));

Assigning a DataTable value to a Variable

I just wrote a simple method to get some data from an SQL server and store it in a DataTable.
Specifically the value is an integer : 666
It is an int datatype on the database and I made a variable called Credits in C# which is also an integer.
The datatable shows the value 666 in the first row so it got added without any problems.
The problem happens when I try to assign Credits = dt.Rows[0] saying
the inputstring was an incorrect format
Ive tried parsing it to an int and adding .ToString() but no matter what it gives the same error.
the latest line I tried was
Credits = Convert.ToInt32(dt.Rows[0].ToString());
But still no luck. I have looked everywhere online for a solution but I cannot find the problem.
Any help would be greatly appreciated.
You are missing column name while selecting data from Data Table. You can either use column name or column index.
int Credits = Convert.ToInt32(dt.Rows[0]["columnname"].ToString());
Please make sure that value of that column value should not be null or empty.If thats the case you have to check that before assigning to int variable.
Or You can use, TryParse
int Credits = int.TryParse(dt.Rows[0]["columnname"].ToString());
You can't assign a entire row inside a variable
string Credits = Convert.ToInt32(dt.Rows[0]["columname"].ToString());

Get values from database to textbox

I have a WinForm that have a DataGridView and a ComboBox, allowing users to select a subject (from the database).
cbxSubject.DataSource = dsSched.Tables["Schedules"];
cbxSubject.DisplayMember = "Subject";
...
The DataGridView looks something like this: http://i45.tinypic.com/18gmmu.png I added the DataGridView since I don't know any other way how to get those values from the database. I used a code, something like this, to get the values:
TextBox1.Text = DataGridView1.Rows[3].Cells[1].Value.ToString();
But then I realized that it won't work anymore if there are more than 2 subjects to choose from, because the code is set to get the value on the 3rd row and the 1st cell. So even when the user changed subject, the output value (w/c are then displayed in a TextBox) will still be the same. Are there any other ways to get those values? Please help, thanks.
You can add a comboxbox this way
DataGridViewComboBoxColumn subjectsCombo = new DataGridViewComboBoxColumn();
subjectsCombo.DataPropertyName = "SubjectID";
subjectsCombo.HeaderText = "Subjects";
subjectsCombo.DataSource = dsSched.Tables["Subjects"];
subjectsCombo.ValueMember = "SubjectID";
subjectsCombo.DisplayMember = "SubjectText";
cbxSubject.Columns.Add(subjectsCombo);
I would suggest that you DONT use constants. Rather that using 3 and 1, you need to write some code to find R and C from what the user selects. It should be event driven and you need to re-set the text box on change. I'm assuming you are using an on-change event, but you haven't actually given us that information yet.
here's some pseudocode to get where im going with this
public DataGridView1_SelectionChanged(object sender, ChangedEventArgs e)
{//this might not be the right event, I'll leave it up to you to do your own homework
int R = //Get the current Selected Row;
int C = //Get the current Selected Cell/column;
TextBox1.Text = dsSched.Tables["Schedules"].Rows[R].Cells[C];
///OR YOU COULD DO SOMETHING LIKE THIS
TextBox1.Text = ((DataGridView)sender).SelectedRows[0].Cells[1].Value;
}
//Please note, this is only pseudocode, I dont like doing peoples homework for them.
This should give you a more generic idea/algorithm that you would need. Keeping in mind that this might not even be the best way to go about doing this, but Its what I would recommend based solely on the information provided to us thus far. btw, what have you tried? and can you give us some larger code examples, there might be a rather more simple mistake being made that you haven't shown us so we cant tell you about it :-)
Considering that you still haven't actually asked the correct question, because we dont know WHY you are trying to do what you have stated you are doing, I can't get any more specific than this. GIGO, you have to ask the right question in order to get the right answer.
I'll try to get some of your doubts out of the way:
I added the DataGridView since I don't know any other way how to get
those values from the database
You already have a DataSet called "dsSched" filled with database values. So, no, you don't need the DataGridView. Just fill whatever you want directly from the DataSet:
string data = dsSched.Tables["Schedules"].Rows[3].Cells[1].Value.ToString();
then I realized that it won't work anymore if there are more than
2 subjects to choose from, because the code is set to get the value on
the 3rd row and the 1st cell.
Well, I'm not sure where you are running that piece of code (TextBox1.Text = Data...), but if you are running it on the SelectedIndexChanged event of the DataGridView, then you should get data from the exact row that the user selected (or something, again, I did not understood what you are trying to do).
One thing that I suspect is that you are under the impression that the code:
TextBox1.Text = DataGridView1.Rows[3].Cells[1].Value.ToString();
...is binding the textbox to the value in the row / cell. That's not how this works - the value is retrieved once when the code is run, and then again whenever the code is run again. So you should make sure the code is run when you have to get this value.
EDIT:
I mean, how do I get the value? Like, the PrimaryKey or something?
That's the question! I'm sorry, I was probably deviating. Just set the [ValueMember][1] to the string that describes the value column of the dataset.
cbxSubject.ValueMember = "Schedule ID";
Than you access it using [SelectedValue][2], like:
int selValue = (int)(cbxSubject.SelectedValue);

List<>.Find(delegate) issue

I have a multi-column combobox where the datasource is a List<> in my Select Class
Select selection = new Select();
RadComboBox1.DataSource = selection.GetAcctUtilCo(e.Text, 10).Skip(e.NumberOfItems);
I have a few DataTextFields. My DataValueField is the AcctID.
Once an account is selected, I need the datatextfield values to populate some fields in a gridview.
I am trying to use the .Find() method by AcctID to retreive the data without success:(
int AcctID = Convert.ToInt32(RadComboBox1.SelectedValue); // *
List<Select> mylist = RadComboBox1.DataSource as List<Select>;
mylist.Find(delegate(SelectTop act) { return act.AcctID == acctID; }); // ** exception here
Label lblAcctNo = (Label)grdAccts.HeaderRow.FindControl("lblAcctNo");
lblAcctNo.Text = mylist.AccountNum;
When I debug, I get 'Object reference not set to the instance of an object' on the indicated line.
AcctID is NOT null when I hover over it. However when I hover over mylist, it says null.
I'm new with the .Find method & I'm really not sure if the problem is with that or with using the datasource of the combobox as mylist source.
Can someone please help enlighten me
Your combo-box's data source is not a list. When you use "as" the result is null if you try to cast to an invalid type, instead of throwing an exception like a standard cast. Since you used the Skip function to create your data source you actually have an "IEnumerable<>".
The problem is caused by RadComboBox1.DataSource - it is not persisted between page requests.
In your code that sets RadComboBox1.DataSource, save a copy of the RadComboBox1.DataSource value in the viewstate. eg. ViewState["RadComboBox1"] = RadComboBox1.DataSource;
In the event that runs your above code, restore the RadComboBox1.DataSource by reading the value from the viewstate. eg. RadComboBox1.DataSource = ViewState["RadComboBox1"];
You should hopefully find the values then persist between requests. Good luck!

How do I set a cell in a DataSet? HELP!

I´m trying to set a cell of type "System.Int32" in a DataSet by code, and my try looks like this:
int aCarID = 5; // as an example...
// points out the row that I want to manipulate - I guess this is what doesn´t work???
int insertIndex = myDataSet.tableCars.Rows.Count
myDataSet.tableCars.Rows[insertIndex]["CarID"] = aCarID;
What happens is: I get an exception of "System.IndexOutOfRangeException".
You´re allowed to say that I´m stupid as long as you provide an answer...
UPDATE!
Yes, I´m trying to create a new row, that´s true - that´s why I´m not using "-1".
So what´s the syntax to create a new row?
If I use tableCars.Rows.Add(...) I need to supply a "DataRow Row" to the Add-function, and I don´t have one to provide - yet! (Catch 22)
NEW UPDATE!
Ooops, found it - "NewRow()" :-)
You do realize that indices start with zero in C#? That means if your table has 3 rows, you're trying to access the 4th row because insertIndex = 3.
Try insertIndex - 1.
Edit: Since you're trying to add a new row and already found out how to do so, also don't forget to save those changes to the database (I assume that's what you want to do). The most simple way is to set the UpdateCommand-property of the DataAdapter you used to fill the DataSet (or actually the DataTable in the DataSet).
You can also have the update commands generated, using a subclass of the DbCommandBuilder.
This is a classic off-by-one: valid rows are at indices 0... Rows.Count -1
If you want to make a new row, call tableCars.AddNew() first.
From MSDN:
An IndexOutOfRangeException exception is thrown when an attempt is made to access an element of an array or collection with an index that is outside the bounds of the array or less than zero.
so the problem is when you use a wrong index as Christian said.
try to create new row first, because you want to access row which doesn't exists, or you have to insert your information into row indexed (insertIndex - 1).
Datarow indexes first position is 0, as in arrays.
You're using a strong-typed dataset, but your insert code is actually for a non-strongly typed dataset.
The following code will work for you (and is much easier!)
var insertRow = myDataSet.tableCars.NewtableCarsRow();
insertRow.CarID = aCarID;
myDataSet.AcceptChanges();
That's it!
NOTE: this code works from .NET version 3.5 onwards. For prior versions, replace the var keyword with tableCarsRow (I'm assuming that you didn't customize the default name for the datarow in the DataSet designer).

Categories

Resources