2013-10-30 118 views
0

我正在嘗試創建「歷史記錄頁面」。閱讀一個用戶的url已經是一個字符串,並將它們添加到List並將其轉換爲DataTable,但是當我點擊show History菜單選項時,我所獲得的只是列「urls」和它下面的空單元格。我假設我也可能不恰當地使用Add方法。List to Datatable。 Datatable不顯示任何值

主窗體類:

private void showHistoryToolStripMenuItem_Click(object sender, EventArgs e) 
{ 
    using (History history = new History()) 
    { 
     history.ShowDialog(); 
     nonHomepage = URLInput.Text; 
     if (String.IsNullOrEmpty(nonHomepage)) 
     { 
     return; 
     } 
     else 
     { 
     addToList(nonHomepage); 
     } 
    } 
} 

public void addToList(string URLvalue) 
{ 
    listH.Add(URLvalue); 
} 

public List<string> getList() 
{ 
    return listH; 
} 

歷史窗體類:

private void History_Load(object sender, EventArgs e) 
{ 
    Form1 br = new Form1(); 
    list = br.listH; 
    DataTable table = ConvertListToDataTable(list); 
    dataGridView1.DataSource = table; 
} 

static DataTable ConvertListToDataTable(List<string> l) 
{ 
    DataTable table = new DataTable(); 
    //int columns = 0; 
    table.Columns.Add("urls"); 
    foreach(string s in l) 
    { 
     table.Rows.Add(s); 
    } 
    return table; 
} 

有什麼建議?如果我將所有這些URL放在文件中,然後從文件中讀取並寫入文本框/表格,該怎麼辦?或者,也許我應該改變數據結構?例如,去字典嗎?提前致謝。

+0

這是否編譯? – Harrison

+0

我沒有調試過這段代碼,我猜想。因爲我認爲問題是當你在表單之間傳遞列表時。更具體地說,這個位:Form1 br = new Form1(); list = br.listH; ...如果您重新實例化該類,則將其所有變量設置爲它們的默認值(並且列表爲空)。 – varocarbas

+0

是的,它編譯。我只需要將主表單中的url字符串傳遞給歷史表單,然後在歷史表單中創建列表呢? – Messerschmitt

回答

1

你的問題是你在private void History_Load(object sender, EventArgs e)創建一個空Form1,並在listH通(裏面是空的)到方法ConvertListToDataTable(list),因此你有空網格。解決的辦法是,你必須改變你的History初始化或顯式調用一些方法LoadData加載實際列表,像這樣:

解決方案1 ​​

public partial class History : Form { 
    public History(){ 
    InitializeComponent(); 
    } 
    public Form1 MainForm {get;set;} 
    private void History_Load(object sender, EventArgs e) {  
    var list = MainForm == null ? new List<string>() : MainForm.listH; 
    DataTable table = ConvertListToDataTable(list); 
    dataGridView1.DataSource = table; 
    } 
    //other code .... 
} 
//Form1 class 
private void showHistoryToolStripMenuItem_Click(object sender, EventArgs e) { 
    //note the MainForm initialization using Property initializer 
    using (History history = new History {MainForm = this}) { 
    history.ShowDialog(); 
    nonHomepage = URLInput.Text; 
    if (String.IsNullOrEmpty(nonHomepage)) { 
     return; 
    } else { 
     addToList(nonHomepage); 
    } 
    } 
} 

解決方案2

//History class 
public partial class History : Form { 
    //define this method to call explicitly before showing your History dialog 
    public void LoadData(List<string> list){ 
    DataTable table = ConvertListToDataTable(list); 
    dataGridView1.DataSource = table; 
    } 
    //other code ... 
} 
//Form1 (or Main Form) class 
private void showHistoryToolStripMenuItem_Click(object sender, EventArgs e) { 
    using (History history = new History()) { 
    history.LoadData(listH);// <---- call this first to load data 
    history.ShowDialog(); 
    nonHomepage = URLInput.Text; 
    if (String.IsNullOrEmpty(nonHomepage)) { 
     return; 
    } else { 
     addToList(nonHomepage); 
    } 
    } 
} 
+0

感謝@KingKing,它現在可以工作,但我可能需要將網址保存到單獨的文件中,以便它能記住以前的會話。你認爲它很方便嗎?它會減慢我的程序嗎?我的意思是始終讀取和寫入文件。 – Messerschmitt

+0

@Messerschmitt如果文件不是太大,我認爲沒關係。即使文件有很多行,您也可以使用'threading'打開並加載到後臺。但我不認爲這是你的情況,所以我們可以正常加載它。 –

+0

謝謝。還有一個問題(我希望我不要求太多)。當用戶用url雙擊該行時,我爲事件編寫了一些代碼,以便將url作爲字符串傳回主窗體並加載到那裏。然而,當我這樣做時,我得到了這個ArgumentOutOfRangeException:form.pageInput.Text = dataGridView1.SelectedRows [0] .ToString();無法弄清楚我在這裏做錯了什麼。是因爲它像一個集合而不是一個字符串? – Messerschmitt

2

添加表格行時,實際上必須添加一行,而不僅僅是一個字符串。

foreach(string s in l) 
    { 
     var row = table.NewRow(); 
     row[0] = s; 
     table.Rows.Add(row); 
    } 
    return table; 

此外,添加一個斷點,並確保您的名單是不是轉換之前空,並確保你的表被正確填充之後。


此外,從架構的角度來看,如果你只有一個信息欄,你真不該使用DataTable,一個List<T>就足夠了。有沒有理由在這裏使用DataTable

+0

實際上,他可以通過依賴字符串填充行(如果列是字符串類型,默認情況下是這樣;他的DataTable人口部分是好的)。 – varocarbas

+0

我是C#的新手,目前正在使用不同的數據結構來找到一個更適合並且安靜快速地存儲和搜索歷史記錄頁面的數據結構。可能會使用收藏夾頁面的相同列表。我還沒有寫任何線程,所以我的程序非常慢。 – Messerschmitt

0

替代語法SpikeX的回答是:

int i = 0; 
foreach (string s in l) 
{ 
     table.Rows.Add() 
     tables.Rows[i].SetField("COLUMN NAME", s); 
     i++ 
} 

我想你只有在表1列,因此使用SetField可能是有點過分了。但是當你有多個列時,閱讀起來要容易一些,而不必回去查看哪一列有哪個索引。

+0

謝謝,但你的和SpikesX都不適合我。 – Messerschmitt

+0

當你嘗試任何變化時會發生什麼? – sab669