[WIN]從型別'DataRowView'至型別'String'的轉換是無效的。
今天幫同事查「從型別'DataRowView'至型別'String'的轉換是無效的。(無法將型別 'System.Data.DataRowView' 的物件轉換為型別 'System.String'。)」的錯誤。
發現寫在ComboBox的SelectedIndexChanged事件中取出ComboBox的SelectedValue轉成字串的值,會出現以上的錯誤! 在別的地方則OK。
看一下「呼叫堆疊」才發現,ComboBox設定DataSource後,會引發它的SelectedIndexChanged事件,而這時ComboBox的ValueMember還沒有指定,所以SelectedValue就會是DataRowView。
記得之前在測試checkedListBox Bind資料時,需要先設定DataSource呀! (請參考:[WIN]checkedListBox Bind資料要注意的地方!)
沒想到ComboBox 先設定DataSource + SelectedIndexChanged事件 + 存取ComboBox的SelectedValue值,居然會變成DataRowView。
於是ComboBox要先設定ValueMember。不過,這樣不就跟設定checkedListBox的順序不同了!
嗯~~~那如果在checkedListBox的SelectedIndexChanged事件中,去存取ComboBox的SelectedValue值,會不會也是一樣的問題呢?
哈,真是出現一樣的錯誤!
好吧,那就改成以下的順序
1.ValueMember
2.DataSource
3.DisplayMember
測試起來,目前都還OK!
程式如下,請先拉一個Button、一個ComboBox及一個checkedListBox。
private void button1_Click(object sender, EventArgs e)
{
DataTable dtResult = new DataTable();
dtResult.Columns.Add("d1", Type.GetType("System.String"));
dtResult.Columns.Add("d2", Type.GetType("System.String"));
dtResult.Rows.Add("d1v1", "d2v1");
dtResult.Rows.Add("d1v2", "d2v2");
dtResult.Rows.Add("d1v3", "d2v3");
comboBox1.ValueMember = "d2";
comboBox1.DataSource = dtResult;
comboBox1.DisplayMember = "d1";
checkedListBox1.ValueMember = "d2";
checkedListBox1.DataSource = dtResult;
checkedListBox1.DisplayMember = "d1";
}
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show((string)checkedListBox1.SelectedValue);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show((string)comboBox1.SelectedValue);
}
使用VS2003測試了一下,發現如果先設定checkedListBox的DisplayMember屬性,再設定DataSource,Item的Text並不會變成System.Data.DataRowView。
目前這個問題只發生在.NET 2.0以上的Windows Form。 Code如下,
DataTable dtResult = new DataTable();
dtResult.Columns.Add("d1", Type.GetType("System.String"));
dtResult.Columns.Add("d2", Type.GetType("System.String"));
dtResult.Rows.Add(new string[] {"d1v1", "d2v1"});
dtResult.Rows.Add(new string[] {"d1v2", "d2v2"});
dtResult.Rows.Add(new string[] {"d1v3", "d2v3"});
checkedListBox1.ValueMember = "d2";
checkedListBox1.DisplayMember = "d1";
checkedListBox1.DataSource = dtResult;
所以就填了問題單回報給Microsoft。有興趣的人可以關注一下哦!
Why checkedListBox DisplayMember property should assign after DataSource property in .NET 2~4.5?
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^