将派生类添加到DataGridView的绑定源

本文关键字:绑定 DataGridView 派生 添加 | 更新日期: 2024-10-22 04:10:18

在带有C#的WinForms中使用MVC模式

三个业务对象——一个抽象的LibraryItem类、一个Book类和一个journal类,都派生自LibraryItem

//LibraryItem Class
public abstract class LibraryItem
{
    public string Title { get; set; }
    private static int _nextCallNum = 1000;
    public int CallNum { get; private set; }
    public int NumCopies { get; set; }
}
//Journal Class
 public class Journal : LibraryItem
{
    public int Vol { get; set; }
}
//Book Class
 public class Book : LibraryItem
{
    public string Author { get; set; }
}

//LibraryController Class 
  public class LibrayController
{
    //a List that can hold both books and journals
    private List<LibraryItem> items;
     //adds a book object to items
     public void AddBookItem(string title, int numCopies , string author) {.....}
      //adds a journal object to items
     public void AddJournal(string title, int vol, int numCopies){}
      //returns a List contaning books and journals to the View
      public List<LibraryItem> GetAllItems()
    {
        return items;
    }
}   

在Win Forms中,使用DataGridView显示LibraryItems 列表

dataGridViewItems.DataSource = null;
booksbindingSource = new BindingSource();
 foreach (LibraryItem anitem in controller.GetAllItems())
        {
            LibraryItem aLibraryItem = (LibraryItem) anitem;
            booksbindingSource.Add(aLibraryItem);
        }
dataGridViewItems.DataSource = booksbindingSource;

当将一本接一本的日记本或一本接另一本的日志添加到绑定源时,我会得到添加到BindingSource列表中的InvalidOperationException对象必须都是相同的类型。

该描述不言自明。我需要一种在数据网格中显示LibraryItems的方法,既可以是书籍也可以是期刊。我只需要在数据网格中显示基类属性(Title、CallNum和NumCopies of LibraryItem)。

将派生类添加到DataGridView的绑定源

如果BindingSourceDataSource属性尚未设置,则添加到列表中的第一个对象将定义列表的类型,然后您要添加到列表的所有项目都应该是第一个对象的类型,因为内部列表必须包含文档中提到的同类类型。

不使用Add方法将项目添加到BindingSource,而是将其DataSource属性设置为从控制器获得的列表

var bs = new BindingSource();
var list = controller.GetAllItems();
bs.DataSource = list;
this.dataGridView1.DataSource = bs;

注意

为了解决这个问题,建议使用上述方法就足够了,但为了查看设置DataSource的影响,您可以将DataSource属性设置为typeof(LibraryItem),您会看到它也能按预期工作:

bs.DataSource = typeof(LibraryItem);
foreach (var item in list)
{
    bs.Add(item);
}
this.dataGridView1.DataSource = bs;