Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allow inserting on DataGridView?

I am binding a DataGridView from a List<T>. I have set on the designer Enable adding.

If the list is null I am creating an empty list so the headers are shown, but it is not creating an empty line for me to be able to add elements. Why? How can I enable the user to add values to this list?

Some code

public IEnumerable<Value> ValueList
{
    get;
    set;
}

private void Form1_Load(object sender, EventArgs ev)
{
    if (ValueList == null)
    {
        ValueList = new List<Value>();
    }

    dataGrid.DataSource = ValueList;
}
like image 419
BrunoLM Avatar asked Apr 07 '11 01:04

BrunoLM


3 Answers

First of all, DataGridView.AllowUserToAddRows must be true (and it is since you are setting it in the designer).

That property says

If the DataGridView is bound to data, the user is allowed to add rows if both this property and the data source's IBindingList.AllowNew property are set to true.

IBindingList.AllowNew (which is not settable) also mentions:

If IList.IsFixedSize or IList.IsReadOnly is true, this property returns false.

Since you are binding to an IEnumerable, I believe IsReadOnly is false. Try exposing the list as a List<T> and binding to a BindingList<T>.

public List<Value> ValueList
{
    get;
    set;
}

private void Form1_Load(object sender, EventArgs ev)
{
    if (ValueList == null)
    {
        ValueList = new List<Value>();
    }

    dataGrid.DataSource = new BindingList<Value>(ValueList);
}
like image 131
Jon Avatar answered Sep 28 '22 01:09

Jon


Adding to Jon's answer: BindingList<T> has an event, AddingRow, which you can listen to, to specifiy the item to be added:

AddHandler _bindingList.AddingNew, Sub(s, args)
                                           args.NewObject = New TicketItem("dawg")
                                       End Sub
like image 42
mike Avatar answered Sep 28 '22 01:09

mike


That property will be false if you have DataGridView.AllowUserToAddRows = true; but do not have default constructor for your binding class. Add default and it should work

public class atsTableInclude
{
    // keep this to allow user to add row
    public atsTableInclude() { }

    public atsTableInclude(string p, bool u)
    {
        Prefix = p;
        Use = u;
    }

    public string Prefix { get; set; }
    public bool Use { get; set; }
}

    public Sorting.SortableBindingList<T> FillAtsList<T>(string jsonfile) where T : class
    {
        if (!File.Exists(jsonfile))
        {
            MessageBox.Show(jsonfile, "File not found");
            return null;
        }

        try
        {
            // load json from file
            using (StreamReader r = new StreamReader(jsonfile))
            {
                string json = r.ReadToEnd();
                var res = JsonConvert.DeserializeObject<List<T>>(json);
                return new Sorting.SortableBindingList<T>(res);                   
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Cannot load json", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        return null;
    }
    private void frmATS_Load(object sender, EventArgs e)
    {        
        string jsonfile2 = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "atsTableInclude.json");
        dataGridView2.DataSource = FillAtsList<atsTableInclude>(jsonfile2);
    }
like image 44
Sasha Bond Avatar answered Sep 28 '22 02:09

Sasha Bond