CAD
CAD

Reputation: 4282

No records are shown in the DataGridView even it's bound to a List

I have bound a List to a DataGridView in the Presenter but when I run the program, only the girds column headings are shown but no rows.

In the View there is a public property encapsulating the DGV...

    public BindingSource Employees
    {
        set { dgvEmployees.DataSource = value; }
    }

In Prsenter's constructor...

  bindingList = new BindingList<IEmployee>(_ModelList); // Presenter has a instance of `List <IEmployee>_ModelList` through the constructor injection
  var source = new BindingSource(bindingList, null);
  _View.Employees = source;

In an event handler method I have data access code...

  _ModelList = _DataService.FilterEmployees(_View.EmployeeName); // DataService returns a List<IEmployee>

Anything missing in my code. In debugging I noted that the _ModelList is being populated with few items from the database but non of them are shown on the grid? What's wrong with this approach?

EDIT1: If I do it like this in the handler method, it's working. But I know this is not the correct way to do.

   BindingSource bindingSource = new BindingSource();   
   bindingSource.DataSource = _DataService.FilterEmployees(_View.EmployeeName);
   _View.Employees = bindingSource ;

EDIT2 : I found another somewhat better way to do this.

In the Presenters constructor...

    bindingList = new BindingList<IEmployee>();
    _View.Employees = bindingList;

Then in the Handler...

    var employees = _DataService.FilterEmployees(_View.EmployeeName);
    foreach (IEmployee emp in employees)
    {
        bindingList.Add(emp);
    }

Finally changed the View's property to...

    public BindingList<IEmployee> Employees
    {
        set { dgvEmployees.DataSource = value; }
    }

Now it's working fine.

Can anybody tell me whats wrong in my first approach?

Upvotes: 2

Views: 287

Answers (2)

TDull
TDull

Reputation: 818

I believe that the cause of your problem (in your first apprach) is this line

var source = new BindingSource(bindingList, null);

Where the second parameter specifies datamember. I'm not sure why you think your second approach, using the parameterless constructor of the bindingsource is incorrect, this is how I would do it.

Note that you can combine using a BindingList and a BindingSource, setting the BindingList as datasource of the BindingSource. This is useful if you wish to add items to the list from code, as the bindinglist has events when items are added or the list is changed.

Upvotes: 2

Kajal Sinha
Kajal Sinha

Reputation: 1565

The following two lines will solve your problem:

        _View.Employees = null;
        _View.Employees = source;

If you bind the same reference to the DataGridView, it won't refresh. Assign null first. This looks like a bug to me with the DataGridView control itself (Someone correct me if I am wrong).

**Update 1:**

You can bind with BindingSource (recommended) or any collection as well. In your new approach you are recreating the list reference which is causing the DataGridView to refresh again. DataGridView can also be refreshed if you remove the refence by assigning its DataSource to null and reassign another reference as I mentioned before.

In your new approach, you are recreating the list instances every time to assign the value and also you won't be able to make use of some good DataBinding features from BindingSource, e.g. MoveNext, MovePrevious, AddNew etc.

Upvotes: 2

Related Questions