15

I had lots of questions related to datasource binding of datagrid. I had a DatagridView to which I am setting DataSource from a list

List<Myclass> li = new List<MyClass>();

MyClass O = new MyClass();
O.Name = "Aden";
O.LastName = "B";
O.Id = 12;
li.Add(O);
O = new MyClass();
O.Name = "Li";
O.LastName = "S";
O.Id = 22;
li.Add(O);

Mydgv.DataSource = li;

Where MyClass is

public Class MyClass
{
 public string Name {get; set;}
 public string LastName {get; set;}
 public decimal Id {get; set;}
}

Now Want to add a new Row to My DataGridView

DataGridViewRow row = (DataGridViewRow)yourDataGridView.Rows[0].Clone();
row.Cells[0].Value = "XYZ";
row.Cells[1].Value = 50.2;
Mydgv.Rows.Add(row);

But it is not possible it raise error because Datasource of Datagrid is Binded with List li. So My first question is how could I do this?

My second question is, For doing this I made a solution to alter my List li and Add New row of data to it and then set it to datasource of datagrid but I think its not a feasible solution is there any better solution?

Even tried to do it by CurrencyManager

CurrencyManager currencyManager1 = (CurrencyManager)BindingContext[MyGrid.DataSource];
currencyManager1.SuspendBinding();
DataGridViewRow row = (DataGridViewRow)yourDataGridView.Rows[0].Clone();
row.Cells[0].Value = "XYZ";
row.Cells[1].Value = 50.2;
Mydgv.Rows.Add(row);
currencyManager1.ResumeBinding();

As I know through it I suspended Binding of DataGrid to provide formatting to Grid as I performed in one of my post Make Row Visible false. But why it doesn't work here in adding row to datagrid?

Community
  • 1
  • 1
Amit Bisht
  • 4,870
  • 14
  • 54
  • 83

5 Answers5

19

Try using a BindingList instead of List:

BindingList<MyClass> li = new BindingList<MyClass>();

Then you add or delete records from the list itself:

li.Add(new MyClass() { Id = 15, LastName = "Z", Name = "Agent" });

and the grid will automatically show that new row.

To have the individual property updates automatically appear in the grid, then your class needs to implement the INotifyPropertyChanged interface:

public class MyClass : INotifyPropertyChanged {
  public event PropertyChangedEventHandler PropertyChanged;

  protected void OnPropertyChanged(string propertyName) {
    if (PropertyChanged != null) {
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
  }

and then your property would have to raise the event:

private string lastName = string.Empty;

public string LastName {
  get { return lastName; }
  set {
    if (value != lastName) {
      lastName = value;
      OnPropertyChanged("LastName");
    }
  }
}

Now if you update a row from code, the grid will show that update:

li[1].LastName = "Q";

Also see Implementing INotifyPropertyChanged - does a better way exist?

Community
  • 1
  • 1
LarsTech
  • 80,625
  • 14
  • 153
  • 225
2

Here is the solution for adding rows to a data source after it is bound to a DataGridView.

Please note that I have used a blank DataGridView "Mydgv" and Button "button1" in the form.

Also I have used the same "MyClass" from your question.

Put one Button named "button1" in the form and write this code

    private void button1_Click(object sender, EventArgs e)
    {
        List<MyClass> li = (List<MyClass>)Mydgv.DataSource;
        MyClass O = new MyClass();

        O.Name = "XYZ";
        O.LastName = "G";
        O.Id = new Random().Next(10, 100);
        li.Add(O);

        Mydgv.DataSource = li.ToList<MyClass>();
    }

Click on the button and you can see your DataGridView is updated with the new row.

Instead of setting the same List object as DataSource try a list of MyClass as I noted below.

Mydgv.DataSource = li.ToList<MyClass>();

To make it easier to understand I put the Id as a Random number between 10 and 100.

Hope you will check it and reply me if there are any problem with the code.

Anoop
  • 379
  • 4
  • 14
  • The solution I suggested is to add new rows to an existing bound DataGridView. If you want solution for any other problem related to this, let me know. I did not get your full requirement, except the one I answered, from your question. – Anoop Dec 12 '13 at 07:15
  • what you did is update DataGridView from list by updating list but i want to update my datgrid not from updating list by manually adding row to datagrid. – Amit Bisht Dec 12 '13 at 07:17
  • What is the difference in both these ways. Anyhow you want to add new rows to datagrid even after databind and that is done. Once a control is databound you cannot update its view. To achieve this its source data need to be changed. – Anoop Dec 12 '13 at 07:38
  • yes that was my question i want to update my view manually not to change in its datasource .. is that any way to suspend binding from datasource – Amit Bisht Dec 12 '13 at 10:42
  • But without a Datasource how will you show values in the Grid? – Anoop Dec 12 '13 at 10:49
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/43035/discussion-between-co-aden-and-anoop) – Amit Bisht Dec 12 '13 at 11:09
0

Follow thos Steps..

  1. Create a Property of ObservableCollection of MyClass.

    private ObservableCollection<MyClass> _li;
    
    public ObservableCollection<MyClass> Li
    {
        get; 
        set
        {
            _li = value;
            NotifyPropertyChangedEvent("Li");      
        }
    }
    
  2. Bind DataGrid DataSource to "Li" property in XAML file.

  3. Now whenever the collection is updated(i.e items added or deleted), the DataSource will update automatically.

Ravi Patel
  • 451
  • 1
  • 6
  • 17
0

create global

List<Myclass> li = new List<MyClass>();

Out side of Page_load or any function

Add/remove any row from li inside of any function and call below line when you change data in li

gridview.DataSource=li;
gridview.DataBind();
Anand
  • 31
  • 5
0

@Co. Aden

As per what I see everything that you did in the first part of binding the list to grid as data source is fine. Execpet that you have missed to call the databind Method after providing the datasource.

Once you call the DataBind method, the details should be displayed on the grid as per what ever you expected.

Mydgv.DataBind();

Sample for Reference:

C#:

public partial class home : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        List<Student> students = new List<Student>();
        for (int i = 0; i < 10; i++)
        {
            students.Add(new Student(){FirstName = "First Name - " +i.ToString(),LastName = "Last Name - "+i.ToString()});
        }
        students.Add(new Student() { FirstName = " ", LastName = " " });
        UsingDataSourceAndDataBind(students);

    }

    private void UsingDataSourceAndDataBind(List<Student> students)
    {
        GridView1.DataSource = students;
        GridView1.DataBind();
    }
}

class Student
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

ASPX Code:

<body>
<form id="form1" runat="server">
<div>
    <asp:GridView ID="GridView1" runat="server">
    </asp:GridView>
</div>
</form>

Venkatesh Ellur
  • 158
  • 1
  • 10