2010-04-20 92 views
2

我有Winform應用程序我正在用C#編寫。在我的表單中,我有一個帶有七個頁面的TabControl,每個頁面都充滿元素(主要是TextBoxes和DropDownLists)。我使用DataReader抽取一些信息,填充一個DataTable,並使用元素的DataBindings.Add方法來填充這些元素與當前值。C#Winforms TabControl元素讀取爲空,直到TabPage選中

用戶可以在這些元素中輸入數據,按「保存」,然後使用元素的文本字段設置UPDATE查詢的參數。例如:

updateCommand.Parameters.Add("@CustomerName", SqlDbType.VarChar, 100).Value = CustomerName.Text; 

我的問題是,一旦予加載的形式中,所有的元件被明顯認爲是空的,直到我手動選擇每個選項卡。因此,如果我在加載表單時立即按下「保存」,TabPages上我尚未選擇的所有字段嘗試用空數據更新(不好)。當我選擇每個TabPage時,這些元素現在將正確地發送它們的數據。目前,我已經制定了一個(非常)醜陋的解決方法,當我第一次填充數據時,以編程方式選擇每個TabPage,但這是一個不可接受的長期解決方案。

我的問題是,如何才能讓TabPages上的所有元素在用戶選擇TabPage之前正確返回其數據?

+2

我不確定發生了什麼,但如果您的控件是數據綁定的,您應該從BindingSource中獲取值,而不是從控件的文本字段中獲取值。 – 2010-04-20 20:08:49

+0

我在使用BindingSource和TabControl中的多個選項卡時遇到了完全相同的問題 – Tommassiov 2015-03-20 15:58:31

回答

7

ho是正確的; TabPage上的元素不會創建,直到選中該TabPage。我只是在表單加載時添加了一個循環來選擇每個TabPage,現在它工作正常。

foreach (TabPage tp in tabControl1.TabPages) 
    { 
     page.Show(); 
    } 
+0

天才。我的生活變得更容易了。簡單ftw! – ImGreg 2012-03-02 14:42:23

4

我不確定你是否可以。以下是來自MSDN的引用:

「TabPage中包含的控件只有在顯示選項卡頁面之後纔會創建,並且只有在顯示選項卡頁面之後,纔會激活這些控件中的任何數據綁定。

但是,並不是讓更新代碼直接從控件獲取值,也許可以創建一個類來保存用於填充控件的DataTable,然後在調用更新代碼時要求該類爲值和類將檢查控件是否已加載,否則將從DataTable中獲取值。

+1

感謝您的回覆。我發現你是對的,頁面需要被選中,雖然我想創建一個基於TabControl的類,但我認爲現在只需循環瀏覽表單加載中的TabPages就容易了。 – 2010-04-20 20:21:51

1

問題是控件不是創建的,直到顯示選項卡。一個解決辦法是對實際加載的頁面,像這樣創建控件:表單上

private static void CreateControls(Control control) 
{ 
    CreateControl(control); 
    foreach (Control subcontrol in control.Controls) 
    { 
     CreateControl(subcontrol); 
    } 
} 
private static void CreateControl(Control control) 
{ 
    var method = control.GetType().GetMethod("CreateControl", BindingFlags.Instance | BindingFlags.NonPublic); 
    var parameters = method.GetParameters(); 
    method.Invoke(control, new object[] { true }); 
} 

然後在構造函數中,你會做這樣的事情:

public Form() 
{ 
    CreateControls(this.tabPage1); 
} 

該解決方案依賴於事實上,有一個內部的CreateControls方法需要一個布爾參數,它可以讓你創建控件,即使它不可見。

0

我對這個問題的解決方法是將下面的代碼添加到表單加載事件;

this.tabcontrol1.BindingContext = this.BindingContext;