Validation on Databoud DataGridView per Column
<p>So I have a DataGridView which is used to display a list of custom models.
Here is some sample code for a model:</p>

<pre><code>public class TestModel
{
    public IEnumerable&lt;string&gt; GetValidationErrors()
    {
        if (Value1 &gt; 100 || Value1 &lt;= 0)
            yield return "Value1 can only be between 1 and 100 (inclusive)";

        if (string.IsNullOrEmpty(Value2))
            yield return "Value2 can not be empty";
    }

    public bool IsValid
    {
        get { return GetValidationErrors().Count() == 0; }
    }

    public int Value1
    {
        get; set;
    }

    public string Value2
    {
        get; set;
    }
}
</code></pre>

<p>Now let's say I was Binding a list (or IEnumerable) of these models like so</p>

<pre><code>List&lt;TestModel&gt; list = Helpers.GetListOfTestModels();
dataGridView1.DataSource = list;
</code></pre>

<p>(We can assume that the list return is valid, or else it wouldn't be stored).</p>

<p>Now on the <code>RowValidating</code> event on the DataGridView, I can validate the entire row by accessing the <code>IsValid</code> property and set a <code>Rows[].ErrorText</code>, like so:</p>

<pre><code>private void dataGridView1_RowValidating(object sender, DataGridViewCellCancelEventArgs e)
{
    var item = dataGridView1.Rows[e.RowIndex].DataBoundItem as TestModel;
    if (item == null)
        return;

    if(!item.IsValid)
    {
        dataGridView1.Rows[e.RowIndex].ErrorText = "Failed Validation"; // Or use GetValidationErrors and concat them, but to be simple I've left that out
        e.Cancel = true;
    }
    else
    {
        dataGridView1.Rows[e.RowIndex].ErrorText = string.Empty;
    }
}
</code></pre>

<p>Now, what I really want to do (without copying and pasting code all over the place), is validate each Property and set the <code>Rows[].Cells[].ErrorText</code> Property (this will show errors per cell, instead of the entire row).</p>

<p>How should I go about this?</p>

<p>Maybe something with Custom Attributes, then reflection to get the property name and access the cell that way?</p>

<p>Hopefully this all makes sense!</p>
