【问题标题】:C#: DataGridView DataSource Update - DataTable, List, BindingList and BindingSource?C#:DataGridView 数据源更新 - DataTable、List、BindingList 和 BindingSource?
【发布时间】:2021-09-15 20:15:55
【问题描述】:

我仍然很困惑如何在更改 DataSource 的内容而不显式触发 DataGridView.Update() 时自动更新 DataGridView。 DataTableListBindingList 作为(直接)DataSource 和作为(间接)DataSource 之间似乎没有任何区别,另外还有一个 BindingSource,它使用前者中的任何一个作为 DataSource。

我实际使用的 DataGridView 是不可编辑的,只显示由相应实体代码更新的条目。我的最后一次尝试是使用 BindingSource,它使用 BindingList 并在代码中操作 BindingSource 的内容。

这里省略了一些方法,对基本问题没有作用。

表格:

private void FormLog_Load(object sender, EventArgs e) {
    ...
    dgvLog.DataSource = Log.Current.SourceEntries;
    ...
}

private void ClearLog() {
    Log.Current.RemoveAll();
}

public void UpdateDataSource() {
    dgvLog.Update();
}

实体(单例类):

public class LogEntry {
    public int ID { get; set; }
    public string DateTime { get; set; }
    public string Type { get; set; }
    public string Event { get; set; }
    public string Details { get; set; }
}

public class Log {
    public BindingList<LogEntry> Entries { get; set; }
    public BindingSource SourceEntries { get; set; }

public Log() {
    Entries = new BindingList<LogEntry>();
    SourceEntries = new BindingSource() { DataSource = Entries };
    ReadAll();
}

public void Add(string type, string logEvent, string details = "") {
    LogEntry entry = MapToDB(new LogEntry() {
        Type = type,
        Event = logEvent,
        Details = details
    });

    DB.Write(QueryAdd(entry));
    SourceEntries.Add(entry);

    if (Config.Current.GetForm("Log") != null)
        ((FormLog)Config.Current.GetForm("Log")).UpdateDataSource();
}

public void ReadAll() {
    for (int i = SourceEntries.Count - 1; i >= 0; i--) {
        SourceEntries.RemoveAt(i);
    }

    DataTable dt = DB.Read(QueryReadAll());
    if (dt != null) {
        foreach (DataRow row in dt.Rows) {
            SourceEntries.Add(MapToList(row));
        }
    }

    if (Config.Current.GetForm("Log") != null)
        ((FormLog)Config.Current.GetForm("Log")).UpdateDataSource();
}

public void RemoveAll() {
    DB.Write(QueryRemoveAll());

    for (int i = SourceEntries.Count - 1; i >= 0; i--) {
        SourceEntries.RemoveAt(i);
    }

    Add("I", "Log cleared");
}

这工作只有当我调用UpdateSource() 调用dgvLog.Update() 通过在另一个我想避免的单例类中使用自写的FormStack。当然,可以简单地在表单本身内调用dgvLog.Update(),但是,尤其是。通过这个日志示例,很明显,当显示 DataGridView 的表单仍在后台打开时,从另一个表单更新数据/在其中更新数据时,这无济于事。

另外,由于没有区别(在使用 DataTable 或 List 等与 BindingSource 之间)我想知道 BindingList 和 BindingSource 的好处/目的是什么:

这是正确的方法还是我错过了什么!?

顺便说一句,我使用的是 .NET v4.5.2。

【问题讨论】:

    标签: c# winforms datagridview binding datasource


    【解决方案1】:

    DataTable、List、BindingList 作为(直接)DataSource 和作为(间接)DataSource 之间似乎完全没有区别,而附加的 BindingSource 使用前者中的任何一个作为 DataSource。

    BindingSource 有几个用途

    • 保持位置/当前行的知识,因此可以实现共享导航(dgv 和文本框都绑定到同一个 BS 意味着 dgv 可以浏览记录并且文本框会更新,因为它们总是显示“当前行”)
    • 提供分类和过滤设施
    • 支持复杂的绑定场景,它必须帮助将列表过滤到不同绑定源中某些当前选定父级的子级
    • 为公共数据源的多个不同位置浏览提供分离

    有效,但仅当我调用 UpdateSource() 时,它通过在另一个我想避免的单例类中使用自写的 FormStack 来调用 dgvLog.Update()。当然,可以简单地在表单本身中调用 dgvLog.Update(),但是,尤其是。通过这个日志示例,很明显,当显示 DataGridView 的表单仍在后台打开时,从另一个表单更新数据/在其中更新数据时,这无济于事。

    Datagridview.Update() 关注为需要它的控件重新绘制区域;它与提交对底层数据模型的更改无关。也许您需要 EndEdit 来完成对当前行的编辑操作并将它们提交到底层数据存储。当您单击网格中的不同行时也会发生这种情况。 Bindingsource 也有一个 EndEdit 方法。大多数情况下,您不需要自己调用这些方法

    要在表单之间共享数据,请传递存储数据的数据表并通过第二个表单中的绑定源绑定它

    另外,由于没有区别(在使用 DataTable 或 List 等与 BindingSource 之间)我想知道 BindingList 和 BindingSource 的好处/目的是什么:

    DataTable 是 DataRow 的集合。 DataRow 的核心是一个对象数组。结束

    绑定列表是您想要的任何内容的列表,例如您的自定义类 Person。可以说最终更有用,但它是在比较苹果和橙子。相反,如果您打开数据集设计器,那么您可以指定具有命名类型列的表。在这方面,它与编写自己的类并没有太大的不同(尽管它在短时间内编写了大量好的代码。我有时将它们用作数据模型

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 2016-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      相关资源
      最近更新 更多