サマーといいます。
通信機器(組み込み,C言語)の開発5年ほど経験があります。Windows環境での開発は
ほんの一ヶ月まえから取り組んでいます。よろしくお願いします。
Windows XP,Visual C++ 2005 .Net Frameworkをつかっています。
以下のコードでコンパイルは通りますが、期待している機能(help.mdfデータベースに
設定してあるデータをlistViewコントロールに表示する)はできていません。
キャストしているところが一番あやしそうですが、どなたが原因わかるでしょうか。
// データベース接続
SqlConnection ^ objConn;
String ^ sConnectionString;
sConnectionString = Data
Source=.\\SQLEXPRESS;AttachDbFilename=C:\\help.mdf;Integrated
Security=True;Connect Timeout=30;User Instance=True;
// コネクションのインスタンス生成
objConn = gcnew SqlConnection(sConnectionString);
objConn->Open();
// データアダプターのインスタンス生成
SqlDataAdapter^ daAuthors = gcnew SqlDataAdapter
(Select * From Main_Table, objConn);
// データセット型のインスタンス生成
DataSet^ dsPubs = gcnew DataSet(Pubs);
// データ読み込み
daAuthors->Fill(dsPubs, Main_Table);
for each ( DataTable^ tblAuthors in dsPubs-
>Tables )
{
for each (DataRow^ row in tblAuthors-
>Rows )
{
// リストビューにデータ表示
array< String^ >^ item1 =
dynamic_cast<array< String^ >^>(row->ItemArray);
listView2->Items->Add(gcnew
ListViewItem(item1));
}
}
デバッガで確認したところrow->ItemArrayにはデータはセットされているようです。
ItemArrayはObject[]すなわち array<Object^>^ ですよね。
それを無理やり array<String^>^ にdynamic_cast して変換できるわけないと思う。
Array::ConvertAll か何かで変換すんじゃないでしょか。
…なんでこんなややこしいコードになるんだろ。
↓こんだけでいいんじゃねぇ?
static String^ obj2str(Object^ x) { return x->ToString(); }
Void button1_Click(Object^ sender, EventArgs^ e) {
SqlConnection^ conn = gcnew SqlConnection(接続文字列);
conn->Open();
SqlCommand^ cmd = conn->CreateCommand();
cmd->CommandText = SELECT 名前,電話番号 FROM 電話帳;;
SqlDataReader^ reader = cmd->ExecuteReader();
while ( reader->Read() ) {
array<Object^>^ item = gcnew array<Object^>(reader->FieldCount);
reader->GetValues(item);
listView1->Items->Add( gcnew ListViewItem(
Array::ConvertAll(item,
gcnew Converter<Object^,String^>(obj2str))) );
}
conn->Close();
}
Converter<Object^,String^>(obj2str))) );
↑ここのobj2strの意味がわかりません。obj2strは関数でしょか?
Converter ジェネリック デリゲート
http://msdn2.microsoft.com/ja-jp/library/kt456a2y.aspx
C++サンプルがのっています。
> すぐに質問し返してこないで、MSDNを調べてみてください。(基本)
(654): String^ obj2str(Object^ x)
{
return x->ToString();
}
for each ( DataTable^ tblAuthors in dsPubs-
>Tables )
{
for each (DataRow^ row in tblAuthors-
>Rows )
{
// リストビューにデータ表示
array<String^>^ item1 = Array::ConvertAll(row-
>ItemArray,gcnew Converter<Object^,String^>(obj2str));
listView2->Items->Add(gcnew
ListViewItem(item1));
}
}
obj2strの意味がよくわからないです。上のようなコードを書きましたが、
(654) : error C2601: 'obj2str' : ローカル関数の定義が正しくありません。
とエラーがでてしまいます。
obj2strにstaticつけていないからです。
なぜstaticが必要なのかは、C++の基本ですのできちんと調べておいてください。
ちなみに、System::Convert::ToStringでも同等のことはできます。
using namespace System;
using namespace System::Collections::Generic;
int main()
{
List< Object^ >^ lst = gcnew List< Object^ >();
lst->Add( 10 );
lst->Add( 2.5f );
lst->Add( DateTime::Now );
lst->Add( Test );
// ※
Converter< Object^, String^ >^ conv;
conv = gcnew Converter< Object^, String^ >( System::Convert::ToString );
List< String^ > slst = lst->ConvertAll( conv );
for each ( String^ s in slst )
{
Console::WriteLine( s );
}
}
// データベース接続
SqlConnection ^ objConn;
String ^ sConnectionString;
sConnectionString = Data
Source=.\\SQLEXPRESS;AttachDbFilename=C:\\kakeibo.mdf;Integrated
Security=True;Connect Timeout=30;User Instance=True;
// コネクションのインスタンス生成
objConn = gcnew SqlConnection(sConnectionString);
objConn->Open();
// データアダプターのインスタンス生成
SqlDataAdapter^ daAuthors = gcnew SqlDataAdapter
(Select * From Main_Table, objConn);
// データセット型のインスタンス生成
DataSet^ dsPubs = gcnew DataSet(Pubs);
// データ読み込み
daAuthors->Fill(dsPubs, Main_Table);
for each ( DataTable^ tblAuthors in dsPubs-
>Tables )
{
for each (DataRow^ row in tblAuthors-
>Rows )
{
// リストビューにデータ表示
Converter<Object^, String^>^
conv;
conv = gcnew Converter< Object^,
String^ >( System::Convert::ToString );
array<String^>^ item1 = Array::ConvertAll(row->ItemArray,
conv);
listView2->Items->Add(gcnew
ListViewItem(item1));
}
}
以上のコードでデータベース接続からデータのリストビューへの表示が可能になり
ました。ご協力ありがとうございました。
以上でこの質問を閉じさせていただきます。
ListViewItemオブジェクトを array< String^ >^ を無理して使わなくても、
ひとつずつ設定していくことも可能です。
String^ connstr =
LData Source=.\\SQLEXPRESS;
LAttachDbFilename=C:\\kakeibo.mdf;
LIntegrated Security=True;
LConnect Timeout=30;
LUser Instance=True;
SqlConnection^ conn = gcnew SqlConnection( connstr );
conn->Open();
SqlDataAdapter^ da = gcnew SqlDataAdapter( LSELECT * FROM Main_Table, conn );
DataSet^ ds = gcnew DataSet();
da->Fill( ds );
DataTable^ dt = ds->Tables[ 0 ];
for each ( DataRow^ dr in dt->Rows )
{
ListViewItem^ item = gcnew ListViewItem();
for ( int i = 0; i < dr->ItemArray->Length; i++ )
{
if ( i == 0 ) item->Text = dr->ItemArray[ i ]->ToString();
else item->SubItems->Add( dr->ItemArray[ i ]->ToString() );
}
this->listView1->Items->Add( item );
}
conn->Close()
解決したのはいいんだけど、ConvertAllを通す意味わかってくれたんかな?
「言われたとおりにやったらできたからOK」
の連続だと何度も同じこと繰り返しますよ。