Hi all,

What I want to do is, when I leave a cell I want to make sure that that cell is not null, that is there is a date data there, and when I leave, I want to add some days to date and place this result on another cell. This is how I tried it.

private void tblgrid1_CellValidating(object sender, DataGridViewCellValidatingEventArgs  e)
        {

            
                DataGridViewRow dgvRow = tblgrid1.CurrentRow;
//here I can't get this code to function even if I'm on right cell....problem here...
               if (dgvRow.Cells["colStartDate"].Selected)
                {

// here I actually want to test if null, appreciate a better code if you have
                    if (Convert.ToDateTime(dgvRow.Cells["colStartDate"].Value) > Convert.ToDateTime("01/01/1900"))
                    {
                       if (Convert.ToInt32(dgvRow.Cells["colDayPast"].Value) > 0 )
                       {
                           dgvRow.Cells["colEndDate"].Value = (Convert.ToDateTime(dgvRow.Cells["colStartDate"].Value)).AddDays(Convert.ToInt32(dgvRow.Cells["colDayPast"].Value)).ToShortDateString();
                       }
                    }
                }

           

        }

I appreciate any help
thanks
snky

Recommended Answers

All 24 Replies

Try this:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace daniweb
{
  public partial class frmGridView4 : Form
  {
    private DataTable dt;

    public frmGridView4()
    {
      InitializeComponent();
    }

    private void frmGridView4_Load(object sender, EventArgs e)
    {
      dt = new DataTable();
      //The string columns are unused
      dt.Columns.Add(new DataColumn("string1", typeof(string)));
      dt.Columns.Add(new DataColumn("string2", typeof(string)));
      dt.Columns.Add(new DataColumn("string3", typeof(string)));
      dt.Columns.Add(new DataColumn("string4", typeof(string)));
      dt.Columns.Add(new DataColumn("Date1", typeof(DateTime)));
      dt.Columns.Add(new DataColumn("Date2", typeof(DateTime)));
      //Date1+Date2 = Date3
      dt.Columns.Add(new DataColumn("Date3", typeof(DateTime)));

      //Get some test rows
      for (int i1 = 0; i1 < 5; i1++)
      {
        DataRow row = dt.NewRow();
        row["string1"] = Guid.NewGuid().ToString();
        row["string2"] = Guid.NewGuid().ToString();
        row["string3"] = Guid.NewGuid().ToString();
        row["string4"] = Guid.NewGuid().ToString();
        dt.Rows.Add(row);
      }


      dataGridView1.AutoGenerateColumns = true;
      dataGridView1.DataSource = dt;

      dataGridView1.Columns[0].DataPropertyName = "string1";
      dataGridView1.Columns[0].Name = "string1";
      dataGridView1.Columns[1].DataPropertyName = "string2";
      dataGridView1.Columns[1].Name = "string2";
      dataGridView1.Columns[2].DataPropertyName = "string3";
      dataGridView1.Columns[2].Name = "string3";
      dataGridView1.Columns[3].DataPropertyName = "string4";
      dataGridView1.Columns[3].Name = "string4";
      dataGridView1.Columns[4].DataPropertyName = "Date1";
      dataGridView1.Columns[4].Name = "Date1";
      dataGridView1.Columns[5].DataPropertyName = "Date2";
      dataGridView1.Columns[5].Name = "Date2";
      dataGridView1.Columns[6].DataPropertyName = "Date3";
      dataGridView1.Columns[6].Name = "Date3";
    }

    private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
    {
      if ((e.ColumnIndex == dataGridView1.Columns["Date1"].Index) ||
          (e.ColumnIndex == dataGridView1.Columns["Date2"].Index))
      {
        DataGridViewRow dr = dataGridView1.Rows[e.RowIndex];
        DateTime dt1, dt2;
        if (DateTime.TryParse(Convert.ToString(dr.Cells["Date1"].Value), out dt1) && (DateTime.TryParse(Convert.ToString(dr.Cells["Date2"].Value), out dt2)))
        {
          //This is just so we dont overflow the dates. This is a nonsensical way to add dates :)
          DateTime dtResult = dt1.AddDays(dt2.Day);
          dataGridView1.Rows[e.RowIndex].Cells["Date3"].Value = dtResult;
        }
      }

    }
  }
}

Thank you Scott,

It is a great effort you are putting in.

I still have problem though,

on < if ((e.ColumnIndex == dataGridView1.Columns["Date1"].Index....> line , when it comes here it does not sense cell_validating event and skips to the end. I adopted your code to mine, I sticked to your grid_cellvalidating event as is.
Could it be some grid config values issue ?

thanks
snakay

You have to click on the grid and wire up the event. Click on the grid, look in your properties window, flip over to the events tab, select the CellValidatingEvent, hit the dropdown, and select the method

O.K. Scott,

that wasn't the problem, I had already done it. It was my mistake from the very beginning, that I mixed up the column names, with wrong column names it would not pass the logical test, therefore nothing to do with event handling. Thanks a lot You have been great help

snakay

You're welcome

Please mark this thread as solved if you have found an answer to your original question and good luck!

ahaa,

still have a curious problem. When I leave the second cell to invoke cellvalidating and get the result to the third column, it doesn't. When I erase the content of second cell and re enter the date and leave the cell, it does work this time and I get the result to the third column

snakay

Err I used the wrong event. Move the code over to the CellValueChanged event.

when I do that I get "System.NullReferenceException was unhandled" exception on

if ((e.ColumnIndex == dataGridView1.Columns["Date1"].Index) ||          (e.ColumnIndex == dataGridView1.Columns["Date2"].Index)) 

line.

You probably don't have a column named "Date1" or "Date2". In the sample I posted I had named the columns:

dataGridView1.Columns[4].DataPropertyName = "Date1";
      dataGridView1.Columns[4].Name = "Date1";
      dataGridView1.Columns[5].DataPropertyName = "Date2";
      dataGridView1.Columns[5].Name = "Date2";
      dataGridView1.Columns[6].DataPropertyName = "Date3";
      dataGridView1.Columns[6].Name = "Date3";

Hi Scott,

I actually use my own column names, I included yours in the message just not to cause any confusion. This line worked well with the previous "CellValidating" event without any problem. My actual code for this line is;

if ((e.ColumnIndex == tblIzinDokum.Columns["colIzinbasla"].Index) || (e.ColumnIndex == tblIzinDokum.Columns["colGunk"].Index))

so I have exception on this line

One of those columns isn't defined then. Put test code in there:

if (tblIzinDokum.Columns["colIzinbasla"] == null)
  System.Diagnostics.Debugger.Break();
else if (tblIzinDokum.Columns["colGunk"] == null)
  System.Diagnostics.Debugger.Break();

See if you hit a breakpoint.

doesn't help I still get "NullReferenceException was unhandled . Check to determine if the object is Null before calling method" error

I think, when grid was populated these columns are null, nothing comes from database, so CellValueChanged is wired at the time of datagridview populating.

I must add, break is caught in the first "if"

if (tblIzinDokum.Columns["colIzinbasla"] == null)  System.Diagnostics.Debugger.Break();

I think objection to null value of colIzinbasla...It is defined it works for the whole application, but initially when populated it is a null cell

No... that means you have a mis-spelling in your column name. That should return the column of the grid regardless of the data. Please double check your names

column names are no problem. I switched to the previos sample with cellvalidating, it works with the defect I mentioned. So the same column names.

upload your project

it is at the bottom of the project

please confirm if you received

Half of the set up for that class is in the designer file which is why I asked you to upload the project, not a file.

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
      foreach (DataGridViewColumn dc in dataGridView1.Columns)
        Console.WriteLine(dc.Name);

See if the column you're after shows up in the output

I notice you're using calls to .Cells and .Columns but I can't tell what class the variables are without the whole project.

here you are

The code is running before the form initializes.

First:

public partial class frmPersizin : Form
    {
      private bool loaded = default(bool); //add this

Next:

private void frmPersizin_Load(object sender, EventArgs e)
        {
            dfHesYil.Text = Convert.ToString(DateTime.Now.Year);

            int Sene = Convert.ToInt32(dfHesYil.Text);
            DateTime d = new DateTime(Sene, 12, 31);
            dfDegerTarih.Text = Convert.ToDateTime(d).ToString("dd/MM/yyyy");

            loaded = true; //add this
        }
private void tblIzinDokum_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
          if (!loaded) //add these two lines
            return;

when I check if columns show, I don't expect them to show at the grid population process. That is to do with program logic. So the columns;

if ((e.ColumnIndex == tblIzinDokum.Columns["colIzinbasla"].Index) || (e.ColumnIndex == tblIzinDokum.Columns["colGunk"].Index))

are not found in the loop. My expectation of the CellValueChanged is when I key enter something into the cells, not when grid is populated in the load.

Apparently CellValueChanged is wired when grid is populating and those columns are not addressed at that point we get exception.

Whereas I only want to trigger an event when I key in something into the cell and right after I leave the cell, first I want cell data be validated and secondly I generate some other values for other cells, which we partly succeeded with cellvalidaring with a funny behavior. This is my interpratation

Later I did the following addition;

if (rbGiris.Checked == true) // this I added now
             {
               if ((e.ColumnIndex == tblIzinDokum.Columns["colIzinbasla"].Index) || (e.ColumnIndex == tblIzinDokum.Columns["colGunk"].Index))

now it works, I think we have to watch out this CellValueChanged event and control it when wired.

If you agree, I will mark this thread as solved

mean time if you check my project if you want to make any other comment which is more then wellcome

Thanks for all your efforts
snakay

I do agree with what you found.

Scott

ok

thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.