C#:DataGridView 数据源更新 - DataTable、List、BindingList 和 BindingSource?

标签 c# winforms datagridview binding datasource

我仍然困惑于如何在不显式触发 DataGridView.Update() 的情况下更改 DataSource 的内容时自动更新 DataGridView。 . DataTable 之间似乎没有任何区别, List , BindingList作为(直接)DataSource 和作为(间接)DataSource 附加 BindingSource它使用前者中的任何一个作为数据源。

我实际为此使用的 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。

最佳答案

It seems there is no difference at all between DataTable, List, BindingList as (direct) DataSource and as (indirect) DataSource with an additional BindingSource which uses any of the former as DataSource.

BindingSource 有一些用途

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

works but only when I call UpdateSource() which calls dgvLog.Update() by using a selfwritten FormStack in another singleton class which I would like to avoid. Of course, one could simply call dgvLog.Update() within the form itself but, esp. with this log example, it is obvious that this does not help when updating data from/within another form while the form that displays the DataGridView is still opened in the background.

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

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

Also, as there is no difference (between using DataTable or List, etc. and BindingSource or not) I wonder what the benefit/purpose of BindingList and BindingSource are:

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

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

关于C#:DataGridView 数据源更新 - DataTable、List、BindingList 和 BindingSource?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68249519/

相关文章:

c# - “如果”语句

c# - SystemSounds.Beep.Play 不发出任何声音

c# - 将 C# 日期时间值与 SQL Server Compact 4 日期时间进行比较

c# - Linq to Xml 到 Datagridview

c# - 捕获失败的授权策略

c# - MediaPlayer 类中的 SetDataSource 从 Assets 或 raw 文件夹加载 mp3 文件

c# - Azure 将 CloudBlockBob URL 更改为与名称不同

c# - 在同一网络上将 Windows Winform 应用程序与 Android 平板电脑连接

c# - 如何在 WinForms 的 ComboBox 中居中对齐所选项目?

c# - 如何使用空行填充datagridview灰色区域