C# DataGridView 动态更改数据源

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9957931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 11:24:00  来源:igfitidea点击:

DataGridView Changing DataSource Dynamically

c#.netdynamicdatagridview

提问by user962206

Basically when I create this DataGridView I have this code to fill it up

基本上当我创建这个 DataGridView 我有这个代码来填充它

public void fillDataGrid(IQueryable<PatientInfo> patients) {

            dgvMyPatients.DataSource = patients;

            dgvMyPatients.Columns["Pat_Last_Name"].DisplayIndex = 0;
            dgvMyPatients.Columns["Pat_First_Name"].DisplayIndex = 1;
            dgvMyPatients.Columns["Pat_Middle_Name"].DisplayIndex = 2;
            dgvMyPatients.Columns["Pat_First_Name"].HeaderText = "First Name";
            dgvMyPatients.Columns["Pat_Last_Name"].HeaderText = "Last Name";
            dgvMyPatients.Columns["Pat_Middle_Name"].HeaderText = "Middle Name";

        }

public IQueryable<PatientInfo> showMyPatients() {

            DbClassesDataContext myDb = new DbClassesDataContext(dbPath);

            var patientInfo = from patients in myDb.PatientInfos
                              where patients.Phy_ID == physcianID
                              select patients;

            return patientInfo;
        }

So when I create my Object I just do this

所以当我创建我的对象时,我只是这样做

fillDataGrid(showMyPatients());

But When I click a button I want to change its contents to something like in this query

但是当我单击一个按钮时,我想将其内容更改为类似于此查询中的内容

 private IQueryable<PatientInfo> searchPatient() {

        DbClassesDataContext myDb = new DbClassesDataContext(dbPath);
        var search = from myPatients in myDb.PatientInfos
                     where (myPatients.Pat_ID == patient_ID && myPatients.Pat_First_Name.Contains(txtSearch.Text)) ||
                     (myPatients.Pat_ID == patient_ID && myPatients.Pat_Last_Name.Contains(txtSearch.Text)) ||
                    (myPatients.Pat_ID == patient_ID && myPatients.Pat_Middle_Name.Contains(txtSearch.Text))
                     select myPatients;

        return search;
    }

Then when I click my button It will do this, but it is not updating the datagrid why is that? fillDataGrid(searchPatient());

然后当我点击我的按钮时它会这样做,但它没有更新数据网格,这是为什么?fillDataGrid(searchPatient());

回答by Dmitry Reznik

For one, you could try setting:

一方面,您可以尝试设置:

DataSource = null;

before updating it. I'd personally recommend using BindingList for binding your data to a dataGridView. This way, you don't have to change dataSource - only the data contained in it. It's used like this:

在更新之前。我个人建议使用 BindingList 将您的数据绑定到 dataGridView。这样,您不必更改 dataSource - 只需更改其中包含的数据。它是这样使用的:

BindingList<PatientInfo> data = new BindingList<PatientInfo>();
dgvMyPatients.DataSource = data;

...
public void fillDataGrid(IQueryable<PatientInfo> patients)
{
    data.Clear();
    data.AddRange(patients);
}

Also, you wouldn't need to feed datagrid schema each time you update a source.

此外,每次更新源时都不需要提供数据网格架构。

UPDATE

更新

Working sample:

工作样本:

public partial class Form1 : Form
{
    private BindingList<SomeClass> _data = new BindingList<SomeClass>();
    public Form1()
    {
        InitializeComponent();

        dataGridView1.DataSource = _data;
        _data.Add(new SomeClass() { First = "1", Second = "1", Third = "1" });
        _data.Add(new SomeClass() { First = "2", Second = "2", Third = "2" });
        _data.Add(new SomeClass() { First = "3", Second = "3", Third = "3" });
        _data.Add(new SomeClass() { First = "4", Second = "4", Third = "4" });
        _data.Add(new SomeClass() { First = "5", Second = "5", Third = "5" });
        _data.Add(new SomeClass() { First = "6", Second = "6", Third = "6" });
        _data.Add(new SomeClass() { First = "7", Second = "7", Third = "7" });
        _data.Add(new SomeClass() { First = "8", Second = "8", Third = "8" });
    }

    private void button1_Click(object sender, EventArgs e)
    {
        _data.Clear();
        _data.Add(new SomeClass() { First = "11", Second = "11", Third = "11" });
        _data.Add(new SomeClass() { First = "21", Second = "21", Third = "21" });
        _data.Add(new SomeClass() { First = "31", Second = "31", Third = "31" });
    }
}

public class SomeClass
{
    public string First { get; set; }
    public string Second { get; set; }
    public string Third { get; set; }
}

回答by Aseem Gautam

Instead if doing

相反,如果做

DataSource = null

its better to refresh the currency manager, given IQueryable returns CurrencyManager:

鉴于 IQueryable 返回 CurrencyManager,最好刷新货币管理器:

 (dgvMyPatients.BindingContext[dataGridView1.DataSource] as CurrencyManager).Refresh();

CurrencyManager

货币经理

CurrencyManager.Refresh()

CurrencyManager.Refresh()

回答by Azhar Khorasany

Change the line:

更改行:

dgvMyPatients.DataSource = patients;

To

dgvMyPatients.DataSource = typeof(List<>);
dgvMyPatients.DataSource = patients.ToList();

回答by Tiw

I had the same problem, after searched and tested a while, finally found the solution:

我遇到了同样的问题,经过一段时间的搜索和测试,终于找到了解决方案:

        DataTable dt = new DataTable();
        dt.Columns.Add("Column One");

        dt.Rows.Add(new object[] { "Item1" });
        dt.Rows.Add(new object[] { "Item2" });
        dt.Rows.Add(new object[] { "Item3.3" });

        this.dataGridView1.AutoGenerateColumns = true;
        this.dataGridView1.Columns.Clear();

        //dataGridView1.DataSource = null;
        dataGridView1.DataSource = dt;

AutoGenerateColumnsneeds be true, that's it.

AutoGenerateColumns需要true,就是这样。