好吧,我面临一个任务,在BCB中,要根据输入的数据在数据库中查找相关的数据,如果有多条记录就需要显示一个ListBox供用户选择。
传统的做法是,用TListBox来显示ListBox……这恐怕用脚后跟都能想到。
例如使用ADOQuery,我们要把Query的DataSet取出需要显示的字段的数据加入ListBox中显示出来。然后根据选择把相应的信息显示或者处理。
这涉及到很多过程:
//从Query读数据出来,加入到ListBox:
while(!ADOQuery1->Eof)
{
AnsiString name = ADOQuery1->FieldByName("Name")->AsString.Trim();
AnsiString num = ADOQuery1->FieldByName("Number")->AsString.Trim();
ListBox1->Items->Add(Name+" "+Number);
ADOQuery1->Next();
}
ListBox1->Show();
…
//在ListBox的OnClick事件中处理选择:
AnsiString text;
text=ListBox1->Items->operator [](ListBox1->ItemIndex);
int i=1;
for(int j=0;j<text.Length();j++)
{
if(text.operator [](i)!=’ ‘)
i++;
}
Edit1->Text=text.SubString(0,i-1);
ListBox1->Clear();
ListBox1->Visible=false;
…
那么我还要根据选择在数据库中读取其他字段怎么办呢?重新根据选择的内容查询?或者当初读出来的数据缓存到一个空间里面和ListBox1的ItemIndex关联?无论怎么做代码都不少写。
在查询很复杂,用户操作步骤很多,或者无法预知用户步骤的时候,我们需要多次对数据集进行操作。在这个时候我们真的必须把数据都读到ListBox中然后再操作吗?当然不用。我们有TDBLookupListBox。
但是我觉得它不够好用,一个投机取巧的办法是直接用DBGrid作为List。谁说List就一定要用ListBox了。把DBGrid属性中的
Option展开,设置:dgTitles、dgIndicator 、 dgColLines
、dgRowLines为false,设置dgRowSelect
为true。然后设置ReadOnly为true,怎么样,能看出来DBGrid和ListBox有什么区别了么?
我们可以再ADOQuery中select需要的字段,加入datasource,在DBGrid中显示出来。而不需要显示出来,却需要用的字段我们可以通过下面的手段隐藏掉。
例:
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add("select Name, Number,Birthday,Address from MemberInfo where Name = :name");
ADOQuery1->Parameters->ParamByName("name")->Value = name;
ADOQuery1->Open();
DBGrid1->Columns[0].operator[](2)->Visible = false;
DBGrid1->Columns[0].operator[](3)->Visible = false;
DBGrid1->Show();
这样Brithday和Address字段我们就看不到了。但是他们就在数据集里面,我们甚至不需要编写多少处理Click事件的代码就可以轻松在Edit中显示想要的数据,或者进一步处理了。
要做的仅仅是在DBGrid的OnCellClick事件中通过简单的ADOQuery1->FieldByName("…")把想要的字段数据取出来并且加入处理过程这么简单了。
有时候,这种办法可以瞬间使得头疼的过程变得轻松异常。一个DBGrid可以起到几个DBLookupListBox的作用,在一些特别的地方可以试试这种特别的ListBox。至少想到这种方法以后,今天就把几个原来查询过程不太人性化的窗体重写了,效果还不错。


