C# datagridview selectionchanged event error - c#

when i work with selectionchanged event in datagridview.
if i click column header it give me that exception:
NullReferenceException was unhandled by user code
Object reference not set to an instance of an object.
it is my code
private void dgvEvents_SelectionChanged(object sender, EventArgs e)
{
//
//Select By EventID Operation.
//
eventID = int.Parse(dgvEvents.Rows[dgvEvents.CurrentRow.Index].Cells["EventID"].Value.ToString());
EventEntity = EventsMethods.SelectByID(eventID);
txtEventName.Text = EventEntity.Name;
cboxEventsCategories.SelectedValue = EventEntity.EventCategoryID;
dateTimePickerEvent.Text = EventEntity.Date.ToString();
txtBenefNum.Text = EventEntity.BeneficiariesNumber.ToString();
txtResultB.Text = EventEntity.ResultBefore.ToString();
txtResultA.Text = EventEntity.ResultAfter.ToString();
txtPercentage.Text = EventEntity.Percentage.ToString();
//
//Show EventsMembers.
//
FillEventsMembersDGV();
}

one of these is returning a null object...
dgvEvents.Rows[dgvEvents.CurrentRow.Index].Cells["EventID"].Value.ToSt‌​ring()
could be any one of these:
dgvEvents
dgvEvents.CurrentRow
dgvEvents.Rows[....]
dgvEvents.Rows[....].Cells
dgvEvents.Rows[....].Cells["EventID"]
dgvEvents.Rows[....].Cells["EventID"].Value
best way to find out, would be to break it into steps:
var curRow= dvgEvents.CurrentRow;
if ( curRow != null )
var index = curRow.Index;
// etc

You're likely getting this error because its trigger the event when it's not a valid selection (ie. -1) thus throwing this exception. Try this:
if ((e.RowIndex >= 0) && (e.ColumnIndex >= 0))
{
//
//Select By EventID Operation.
//
//Also, use Convert.ToString() rather than .ToString();
eventID = int.Parse(Convert.ToString(dgvEvents.Rows[dgvEvents.CurrentRow.Index].Cells["EventID"].Value));
EventEntity = EventsMethods.SelectByID(eventID);
txtEventName.Text = EventEntity.Name;
cboxEventsCategories.SelectedValue = EventEntity.EventCategoryID;
dateTimePickerEvent.Text = EventEntity.Date.ToString();
txtBenefNum.Text = EventEntity.BeneficiariesNumber.ToString();
txtResultB.Text = EventEntity.ResultBefore.ToString();
txtResultA.Text = EventEntity.ResultAfter.ToString();
txtPercentage.Text = EventEntity.Percentage.ToString();
//
//Show EventsMembers.
//
FillEventsMembersDGV();
}

Related

How to stop error when clicking index greater than 0 in datagridview?

I am trying to open a form when I click a row in a datagridview and populate the textboxes within the new form. I am able to click the first row (index zero) and it does what I am trying to achieve. But if I click any other row, I get an error:
Here is my code:
private void dataGridViewActivityHire_CellClick(object sender, DataGridViewCellEventArgs e)
{
try
{
EditFormHire form2 = new EditFormHire();
var table = dataGridViewActivityHire;
string name = table.SelectedRows[e.RowIndex].Cells[0].Value.ToString();
string type = table.SelectedRows[e.RowIndex].Cells[1].Value.ToString();
string cost = table.SelectedRows[e.RowIndex].Cells[3].Value.ToString();
DateTime start = Convert.ToDateTime(table.SelectedRows[e.RowIndex].Cells[4].Value);
DateTime end = Convert.ToDateTime(table.SelectedRows[e.RowIndex].Cells[5].Value);
form2.CustomerName = name;
form2.Registration = textBoxRegistration.Text;
form2.ActivityType = type;
form2.DailyHireCost = textBoxDailyHireCost.Text;
form2.Total = cost;
form2.StartDate = start;
form2.EndDate = end;
form2.ShowDialog();
}
catch (Exception error)
{
MessageBox.Show(error.Message);
}
}
I find it odd that I can click the first index and it works correctly, but any index > 0 returns that error. Anyone know what could be causing this?

Variable in other function has always value zero

I have problem with one variable.
protected void godziny_Click(object sender, EventArgs e)
{
var id_filmu = Request["id"];
var data = Request["data"];
var godzina = TimeSpan.Parse(hidden2.Value);
var query = from h in bazaDC.seanses
where h.godzina == godzina && h.id_filmu == int.Parse(id_filmu) && h.data == DateTime.Parse(data)
select h;
foreach (var a in query)
{
Session["id_seansu"] = a.id_seansu;
}
}
id_seansu is declared outside function, just in partial class. I have to get that variable in another function:
protected void rezerwujButton_Click(object sender, EventArgs e)
{
DateTime dzisiejszaData = DateTime.Today;
TimeSpan godzinaRezerwacji = DateTime.Now.TimeOfDay;
DateTime dataZarezerwowania;
TimeSpan czasZarezerwowania;
var query = from wszystkieRezerwacje in bazaDC.rezerwacjes
select wszystkieRezerwacje;
foreach(var i in query)
{
if(i.data_rezerwacji.HasValue && i.czas_rezerwacji.HasValue)
{
dataZarezerwowania = i.data_rezerwacji.Value;
czasZarezerwowania = i.czas_rezerwacji.Value;
}
}
rezerwacje nowaRezerwacja = new rezerwacje();
if (Session["id_seansu"] != null)
{
Response.Write(Session["id_seansu"]);
};
/*nowaRezerwacja.imie_klienta = imieTextBox.Text;
nowaRezerwacja.nazwisko_klienta = nazwiskoTextBox.Text;
nowaRezerwacja.email_klienta = emailTextBox.Text;
nowaRezerwacja.nrtel_klienta = nrKomTextBox.Text;
nowaRezerwacja.numer_miejsca = Hidden1.Value;
nowaRezerwacja.data_rezerwacji = dzisiejszaData;
nowaRezerwacja.czas_rezerwacji = godzinaRezerwacji;
nowaRezerwacja.id_seansu = id_seansu;
bazaDC.rezerwacjes.InsertOnSubmit(nowaRezerwacja);
bazaDC.SubmitChanges();*/
}
But when I wanna write that variable by Response.Write("id_seansu") in rezerwujButton_Click It is always "0".
But when I wanna write it in godziny_Click It have correct value.
Why variable is getting 0 value in another function?
When you perform the first click, the page will post back and hence the value of the variable get reset, to Persist Variable on Postback you have to use either session or ViewState, if the you want this variable in other pages then you can go ahead with session if it is specifically for this page then you have to opt ViewState. You can assign like this:
ViewState.Add("id_seansu","some value");
And get value like this:
if (ViewState["id_seansu"] != null)
{
var id_seansu = ViewState["id_seansu"];
}

Input a value from a combobox, while committing an Add in DataGridView

Using C# and forms. I have a datagridview which has two of the three fields visible in the table which is editable and addable. The third field is in a combobox.
When updating the database (hitting enter after adding in the empty row) I get an error saying that the third field can't be null. I'd like to have the value in the combobox be used for the third field.
I can't seem to figure it out. Should I be using an event, somehow?
private void cmbMCID_SelectedIndexChanged(object sender, EventArgs e)
{
var cMarks = (from cm in DB.Student_Courses
where cm.CID == Convert.ToInt32(cmbMCID.Text)
select cm).ToList();
Student_Course sc = new Student_Course();
//cMarks.Add(sc);
studentCourseBindingSource.DataSource = cMarks;
sc.CID = Convert.ToInt32(cmbMCID.Text);
//studentCourseBindingSource.ResetBindings(false);
}
I've attempted to added a RowsAdded Event but didn't come out on top.
private void dgvSMarks_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
if (tabControl1.SelectedIndex == 3)
{
Student_Course sc = new Student_Course();
sc.CID = Convert.ToInt32(cmbMCID.Text);
}
}
Great, OK. so I was doing horrible things - with the combobox. A mix of needing to making a selection in the combobox first (otherwise returned null) and trying to commit what was already in the database.
Needed to create a for loop through the dgv collection, too.
private void dgvSMarks_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
// if (dgvSMarks.ContainsFocus == true)
// {
// // Get the RowIndex of the CID Cell, and add the combobox MCID value to it
// dgvSMarks.Rows[e.RowIndex-1].Cells[0].Value = Convert.ToInt32(cmbMCID.Text);
// }
var student_course = new Student_Course();
var course = new Course();
//MessageBox.Show("Row Count is " + dgvSMarks.Rows.Count);
for (int i = 1; i < dgvSMarks.Rows.Count; i++)
{
if (i == (dgvSMarks.Rows.Count - 1))
{
student_course.CID = Convert.ToInt32(cmbMCID.Text);
student_course.SID = Convert.ToInt32(dgvSMarks.Rows[i - 1].Cells[1].Value);
student_course.Mark = Convert.ToInt32(dgvSMarks.Rows[i - 1].Cells[2].Value);
DB.Student_Courses.InsertOnSubmit(student_course);
DB.SubmitChanges();
}
}
}
Thanks to the help of my CPI instructors. :)

How to Load all the Objects in an Array List

I am trying to figure out how to load through an Array List of Objects. I am able to retrieve the last Object in the Array, but it will not let me Load any other Object after that. here is part of the code I have. As you can see it saves the object to the List, but when I click the loadLastBtn it will only load the most recent entry and if I hit it again after that nothing loads.
List<Members> lstMembers = new List<Members>();
private int hold;
private void submitBtn_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(firstNameTxt.Text) || string.IsNullOrEmpty(lastNameTxt.Text)
|| string.IsNullOrEmpty(userNameTxt.Text) ||
string.IsNullOrEmpty(passwordTxt.Text) || string.IsNullOrEmpty(confPassTxt.Text)
|| string.IsNullOrEmpty(majorBox.Text) || string.IsNullOrEmpty(specialtyBox.Text))
{
MessageBox.Show("You must enter in all fields before moving forward");
}
else
{
Members m1 = new Members(firstNameTxt.Text, lastNameTxt.Text, userNameTxt.Text,
passwordTxt.Text, confPassTxt.Text, majorBox.Text,
specialtyBox.Text);
lstMembers.Add(m1);
}
}
private void loadLastBtn_Click(object sender, EventArgs e)
{
firstNameTxt.Text = lstMembers[hold].FirstName;
lastNameTxt.Text = lstMembers[hold].LastName;
userNameTxt.Text = lstMembers[hold].UserName;
passwordTxt.Text = lstMembers[hold].Password;
confPassTxt.Text = lstMembers[hold].ConfPassword;
majorBox.Text = lstMembers[hold].Major;
specialtyBox.Text = lstMembers[hold].Specialty;
hold++;
}
I have edited my answer. this will now print each user one by one each time I hit loadLastBtn, but it does show them from the first user to the last, where I need it to shower the last user to the first.
What you need is something like this:
// -1 Indicates that you should start at the end of the list
int index = -1;
private void loadButton_Click(object sender, EventArgs e)
{
if (members != null && members.Count > 0) // Avoid accessing if list is empty or null
{
if (index == -1)
index = members.Count - 1;
firstNameTxt.Text = lstMembers[index].FirstName;
lastNameTxt.Text = lstMembers[index].LastName;
userNameTxt.Text = lstMembers[index].UserName;
passwordTxt.Text = lstMembers[index].Password;
confPassTxt.Text = lstMembers[index].ConfPassword;
majorBox.Text = lstMembers[index].Major;
specialtyBox.Text = lstMembers[index].Specialty;
if (index == 0) // Reached beginning of array
index = -1; // Indicate that next time the last element must be accessed
else
--index;
}
}
private int hold = lstMembers.Count -1;
private void loadLastBtn_Click(object sender, EventArgs e)
{
firstNameTxt.Text = lstMembers[hold].FirstName;
lastNameTxt.Text = lstMembers[hold].LastName;
userNameTxt.Text = lstMembers[hold].UserName;
passwordTxt.Text = lstMembers[hold].Password;
confPassTxt.Text = lstMembers[hold].ConfPassword;
majorBox.Text = lstMembers[hold].Major;
specialtyBox.Text = lstMembers[hold].Specialty;
hold--;
}

C# DataGridView Stay Focused on Last Record

I have a DataGridView where I am scanning in checks from a keyboard emulated device.
While keypreview is on and I'm waiting for input, the user cannot type anything in otherwise it grabbed by my method to read the input by the check reader. All this is working fine.
After the scan, I am adding to the datagridview a row, which is being put at the end.
How do I make the datagridview scroll to the bottom after each add? I wind up with a few hundred checks and it's at the top. So, every time they scan, they have no idea what was scanned in.
This is my method that creates the row:
private void Timer1Tick(object sender, EventArgs e)
{
_secondswaited += 1;
if (_secondswaited == SecondsToWait)
{
timer1.Enabled = false;
var psc = new ParseScannedCheckNumbers();
if (psc.ParseCheck(_checkData))
{
label_Status.Text = #"Scan Next Check";
var ct = checkTrans.IndividualCheck.NewIndividualCheckRow();
ct.Date = DateTime.Now.ToShortDateString();
ct.AccountNumber = GetAccountNumber(psc.BankAccountNumber);
ct.Name = GetAccountName(ct.AccountNumber);
ct.AccountBalance = GetAccountBalance(ct.AccountNumber);
//ct.CheckAmount = 0;
ct.BankRoutingNumber = psc.BankRoutingNumber;
ct.BankAccountNumber = psc.BankAccountNumber;
ct.CheckNumber = psc.CheckNumber;
ct.Status = "Entered";
checkTrans.IndividualCheck.Rows.Add(ct);
var dgvcount = dgv_Checks.Rows.Count;
**dgv_Checks.Rows[dgvcount - 1].Selected = true;**
}
else
{
label_Status.Text = #"Scan failed. Rescan check.";
}
_checkData = string.Empty;
_secondswaited = 0;
var rs = new Registry.RegistrySettings();
if (!rs.ScanChecksContinuous)
{
StopScanning();
label_Status.Text = #"Success!";
EditLastRowEntered();
}
label_ChecksScanned.Text = (dgv_Checks.RowCount - 1).ToString();
}
}
The part that is bold is where I attempted to move to the last row, without success.
Thanks!
I'd use the DataGridView.CurrentCell property. Try this in place of the line you're having problems with:
dgv_Checks.CurrentCell = dgv_Checks.Rows[dgvcount - 1].Cells[0];
What i think you need to do is check to see if the Row is being displayed.
and then
replace the line in bold with
if(dgv_Checks.Rows[dgvcount - 1].Displayed == false)
{
dgv_Checks.FirstDisplayedScrollingRowIndex = dgvcount - 1;
}

Categories