簡體   English   中英

C#:DataGridView 數據源更新 - DataTable、List、BindingList 和 BindingSource?

[英]C#: DataGridView DataSource Update - DataTable, List, BindingList and BindingSource?

我仍然不知道如何在更改 DataSource 的內容時自動更新 DataGridView 而不顯式觸發DataGridView.Update() 似乎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。

DataTable, List, BindingList as (direct) DataSource 和 as (indirect) DataSource 之間似乎沒有任何區別,附加的 BindingSource 使用前者作為數據源。

BindingSource 有幾個用途

  • 維護位置/當前行的知識,因此可以實現共享導航(dgv 和文本框都綁定到同一個 BS 意味着 dgv 可以瀏覽記錄並且文本框更新,因為它們總是顯示“當前行”)
  • 提供分類和過濾設施
  • 支持復雜的綁定場景,它必須幫助將列表過濾到不同綁定源中某些當前選定父項的子項
  • 為公共數據源的多個不同位置瀏覽提供分離

工作,但只有當我調用 UpdateSource() 時,它調用 dgvLog.Update() 通過在另一個我想避免的單例類中使用自寫的 FormStack 。 當然,人們可以簡單地在表單本身中調用 dgvLog.Update() 但是,尤其是。 對於這個日志示例,很明顯,當顯示 DataGridView 的表單仍然在后台打開時,從另一個表單中更新數據時這沒有幫助。

Datagridview.Update() 負責為需要它的控件重新繪制區域; 它與提交對底層數據模型的更改無關。 也許您需要 EndEdit 來完成對當前行的編輯操作並將它們提交到底層數據存儲。 當您單擊網格中的不同行時,也會發生這種情況。 Bindingsource 也有一個 EndEdit 方法。 大多數情況下,您不需要自己調用這些方法

要在表單之間共享數據,請傳遞數據存儲在其中的數據表,並通過第二個表單中的綁定源將其綁定

此外,由於沒有區別(使用 DataTable 或 List 等與 BindingSource 與否)我想知道 BindingList 和 BindingSource 的好處/目的是什么:

DataTable 是 DataRow 的集合。 DataRow 的核心是一個對象數組。 結束

綁定列表是您想要的任何內容的列表,例如您的自定義類 Person。 最終可以說更有用,但它是在比較蘋果和橙子。 相反,如果您打開數據集設計器,那么您可以指定具有命名類型列的表。 在這方面,它與編寫自己的類並沒有太大的不同(盡管它在短時間內編寫了大量好的代碼。我有時將它們用作數據模型

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM