簡體   English   中英

從另一個表單(子)訪問 DatagridView 時出現問題

[英]Problem accessing DatagridView from another form (child)

我在 Form1 上有一個 datagridView。 當我雙擊該 Datagridview 中的一個項目時,我會轉到一個詳細信息窗體,在那里我可以看到 datagridview 中該行的詳細信息。 (我根據我在 datagridview 中保存的記錄的 id 獲取它們)。 現在我想在 detailform 上制作上一個/下一個按鈕,這樣用戶就不必返回到 form1。

我可以訪問 datagridview(它是公共的),但看不到行信息。

在調試器中,如果我從this.Owner.Controls[0].Controls[2].Controls[0]開始,然后單擊以打開Rows屬性,我可以看到行信息。 當我輸入this.Owner.Controls[0].Controls[2].Controls[0].Rows[0]時,出現錯誤 CS1061。

我怎樣才能解決這個問題?

這是一個數據類型問題。 看這個表達式:

this.Owner.Controls[0].Controls[2].Controls[0].Rows[0]

我們可以從頭到尾按照表達式各部分的數據類型來看問題。

首先, this的類型是當前 Form,它將繼承自System.Windows.Forms.Form 從那里,我們檢查該類型的.Owner屬性,並看到它也是一個(可為空的) System.Windows.Forms.Form

現在我們開始查看Form類型的.Controls成員。 我們通過了解Form繼承自System.Windows.Forms.Control來找到數據類型,這將我們引向屬性定義 現在我們知道我們正在查看System.Windows.Forms.ControlCollection 這種類型有一個索引器屬性,允許您進行[0][2]查找(通過名稱可能更好,fwiw)。 此屬性的文檔告訴我們索引器表達式的結果返回到System.Windows.Forms.Control

現在我們已經足夠了解當我們采用這個表達式時:

this.Owner.Controls[0].Controls[2].Controls[0]

表達式的數據類型鏈如下所示:

this   .Owner .Conrols            [0]       .Controls           [2]       .Controls           [0]
Form > Form > ControlCollection > Control > ControlCollection > Control > ControlCollection > Control

它顯示最終結果是System.Windows.Forms.Control 從那里我們去尋找.Rows屬性並找到......什么都沒有。 基本Control類型不提供此屬性。

那么為什么它在調試器中工作呢? 在運行時,我們不處理基本的Control對象。 我們正在處理從Control繼承的類型,例如 Panel、TextBox 或 DataGridView。 恰好DataGridView控件確實提供了Rows屬性。 調試器允許您解決此問題以使用運行時類型,但編譯器不知道程序開始運行后會發生什么; 它必須更嚴格。 例如,您可能有一個按鈕可以刪除 gridview 並在那里放置其他東西,現在Rows表達式將不再有效。

您可以通過強制轉換解決編譯器問題:

var dgv = (DataGridView)this.Owner.Controls[0].Controls[2].Controls[0];
var row = dgv.Rows[0];

但這與表單布局緊密相關。 在設計器中四處移動一些東西,突然間您正在跟蹤大量代碼以找出問題所在。 在將其顯示在屏幕上之前,您最好直接在子窗體中設置對 DataGridView 的引用。

var child = new detailForm(this);
child.ParentGrid = this.DataGridView1; // assuming you declare a public property named "ParentGrid" and your control is named DataGridView1
child.ShowDialog();

最后,您可能想知道是否需要為您使用的每一行代碼都處理這樣的數據類型表達式鏈。 我想說的是,您應該了解在每個表達式的每個級別上使用的數據類型。 幸運的是,這並不意味着您需要記住所有內容。 理解 Windows 窗體類型通常如何組合在一起並不需要太多經驗,因此您可以理解這些數據類型,而不必逐一閱讀文檔。 談到“通過文檔追逐。當你真的不知道時,你應該知道如何閱讀文檔來找到答案。

假設這是一個只讀操作,我會將DataGridView傳遞給詳細信息表單。 您可以為采用DataGridView作為參數的詳細信息表單創建一個構造函數,或者創建某種在表單構造函數之后調用的public void Populate(DataGridView dgv) { }函數。

如果您打算從詳細信息頁面更改DataGridView中的數據,並希望它反映在主窗體上,那么您可以在主窗體偵聽的詳細信息窗體上創建一個事件,或者在詳細信息窗體關閉后,檢索存儲的DataGridView並查找更改(或只是覆蓋)。

暫無
暫無

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

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