Question

I have a DataGridView control on my form. It has 6 columns and 6 rows (which will never change). When a user enters data in a cell under any column, I want to make sure they fill in the rest of the cells for that row. So basically if they put data in row 0 – column 0, I want to ensure that row 0 – column 1, row 0 – column 2 and so on... have data in them. I need this for validation reasons before this will be committed to the database. If the fields are not all filled in for that row, I want to display a message containing the rows that need to be fixed.

Any help is greatly appreciated!

Here's an update, I have figured out what needed to be done.

Private Sub ValidateYear()

    Dim oInvYear As New Collection
    Dim oErrorMsg As New System.Text.StringBuilder
    Dim blnErrFound As Boolean = False

    'Loop through year column and check for number, if blank skip'
    For i As Integer = 0 To dgvIntervals.Rows.Count - 1
        If Not String.IsNullOrEmpty(dgvIntervals.Rows(i).Cells(4).Value) Then
            If Not IsNumeric(dgvIntervals.Rows(i).Cells(4).Value) Then
                oInvYear.Add(i + 1)
                blnErrFound = True
            End If
        End If
    Next

    'If errors found, lets append them to our message'
    If blnErrFound Then
        oErrorMsg.Append("PLEASE FIX ERRORS BELOW BEFORE PROCEEDING")
        oErrorMsg.AppendLine("")
        oErrorMsg.Append(vbCrLf)

    'Get our year count errors'
    If oInvYear.Count > 0 Then
        oErrorMsg.Append("* Year must be a number- ")
        oErrorMsg.Append("Line(s): ")
        For i As Integer = 1 To oInvYear.Count
            If i >= 2 Then
                oErrorMsg.Append(", ")
            End If
            oErrorMsg.Append(oInvYear.Item(i).ToString)
        Next
        oErrorMsg.Append(vbCrLf)
    End If

    'Show them to our user'
    MsgBox(oErrorMsg.ToString)

End Sub 
Was it helpful?

Solution

Use the CellValidating or RowValidating events of the DataGridView control to validate the data that has been entered by the user.

Private Sub OnRowValidating(ByVal sender As Object, ByVal args As DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating
  Dim row As DataGridViewRow = DataGridView1.Rows(args.RowIndex)
  For Each cell As DataGridViewCell In row.Cells
     If String.IsNullOrEmpty(cell.Value.ToString()) Then
        'show a message box or whatever...
     End If
  Next
End Sub

OTHER TIPS

Well in this scenario I recommend you to read every cell from every row that you have, and when you find a value in any cell you need to make sure that there are values for the other cells.

I did a little sample for you, I hope this help you with your problem.

At first I created this entity to fill my gridview:

  public class MyEntity
    {
        public string ID { get; set; }

        public string Name { get; set; }

        public string LastName { get; set; }
    }

This is the code on my aspx page

<form id="form1" runat="server">
    <div>
        <asp:GridView ID="grvData" runat="server" AutoGenerateColumns="false">
            <Columns>
                <asp:TemplateField HeaderText="ID" >
                    <ItemTemplate >
                        <asp:Label ID="lblID" runat="server" Text='<%# Eval("ID") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField  HeaderText="Name">
                    <ItemTemplate>
                        <asp:TextBox ID="txtName" runat="server" Text='<%# Eval("Name") %>'></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField  HeaderText="Last Name">
                    <ItemTemplate>
                        <asp:TextBox ID="txtLastName" runat="server" Text='<%# Eval("LastName") %>'></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
        <br />
        <asp:Button ID="btnValidate" runat="server" Text="Validate" OnClick="btnValidate_Click" />
        <br />
        <asp:Label ID="lblMessage" runat="server" ForeColor="Red" Text="">

        </asp:Label>
    </div>
    </form>

Then on my code behind

public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                List<MyEntity> data = GenerateData();
                this.grvData.DataSource = data;
                this.grvData.DataBind();
            }
        }

        protected void btnValidate_Click(object sender, EventArgs e)
        {
            int columns = this.grvData.Columns.Count - 1;
            foreach (GridViewRow row in this.grvData.Rows)
            {
                int count = columns;
                TextBox tbName = row.Cells[1].FindControl("txtName") as TextBox;
                TextBox tbLastName = row.Cells[2].FindControl("txtLastName") as TextBox;
                if (!string.IsNullOrWhiteSpace(tbName.Text))
                {
                    count--;
                }
                if (!string.IsNullOrWhiteSpace(tbLastName.Text))
                {
                    count--;
                }
                if (count != columns && count != 0)
                {
                    this.lblMessage.Text = "Invalid input, you need to supply data for every field.";
                    break;
                }
            }
        }

        private List<MyEntity> GenerateData()
        {
            List<MyEntity> list = new List<MyEntity>();
            for (int i = 0; i < 5; i++)
            {
                MyEntity entity = new MyEntity() { ID = Guid.NewGuid().ToString() };
                list.Add(entity);
            }
            return list;
        }
    }

As you can see is pretty simple, I would not recommend you to use this approach if you are loading too many records with many columns, because that could affect performance, but in your case I think this should works.

PS. My answer is with visual C#, because when I read it you did not mention the language, and now you just changed it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top