線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:6083
推到 Plurk!
推到 Facebook!

ComboBox的item對應動態的Form

答題得分者是:dllee
sugizo656
一般會員


發表:6
回覆:8
積分:2
註冊:2005-08-02

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-09-14 15:23:00 IP:220.130.xxx.xxx 訂閱
我要做的功能是,點選Form1下的ComboBox選項,他會彈出對應的動態視窗,每個視窗下各有OpenDialog指定的圖片
而關閉某一動態視窗時,Form1下的ComboBox選項也會刪除該個item
例如:
按1->彈出動態視窗A(含 Image1)
2->彈出動態視窗B(含 Image2)
類推...


因為是用動態產生Form的方式,所以一開始的想法是用ComboBox下的itemindex去抓取對應的Form
例如:
void __fastcall TConvolution_From::ComboBox1Click(TObject *Sender)
{
MainForm->Im[ComboBox1->ItemIndex]->Show();
}
Im為TMyForm *Im[20];

而遇到的困難是,假設關閉了一個Im視窗,並得使ComboBox下的item也去掉其選項
ComboBox會將剩餘的選項重新排列其itemindex
也就是說選項1.2.3 [ index: 0,1,2 ]-->對應MyForm1.2.3
關閉了MyForm2後,ComboBox選項(1).(3)的index會變成0,1
所以再按下選項(3)時,index1會去開啟已經被關閉的MyForm2,造成error訊息


請問我該怎麼讓ComboBox下的選項能自動跟隨MyForm視窗而新增or刪除item
但又能讓剩下的item對應"原本"的MyForm視窗呢?










我搜尋過之前的文章了,沒有找達適合的解答
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-09-14 23:01:25 IP:59.105.xxx.xxx 訂閱
看了您的問題,可能您還不了解如何善用 TStrings 這個 VCL 元件。
TStrings 在很多 VCL 元件都可以看到它的蹤跡,如果您認為 TStrings
只是存一堆字串,那您可能就只用了它 50% 不到的功能了。
TStrings 好用之處,在於它可以設定一個字串 AnsiString ,
同時,將一個 TObject(或繼承自TObject的VCL) 與字串放在一起
有個對應。
也許,我說了半天,可能您還不知道與您的問題有什麼關係吧

在 ComboBox 內的 Items 就是一個 TStrings,您可能只在 Form1 內使用
[code cpp]
ComboBox1->Items->Add("A 視窗名稱");
ComboBox1->Items->Add("B 視窗名稱");
[/code]
您可以試試
[code cpp]
TMyForm *A=new TMyForm(Application);
ComboBox1->Items->AddObject("A 視窗名稱",A);
TMyForm *B=new TMyForm(Application);
ComboBox1->Items->AddObject("B 視窗名稱",B);
[/code]
這樣 A 表單就與 "A 視窗名稱" 連在一起了。
同時,以上也是新增的方法。
以下則說明刪除的方法。
假設 ItemIndex 原本可能是
[code cpp]
// 先使用 TStrings 的 Objects 取出 TMyForm
TMyForm *NeedDelete=(TMyForm*)ComboBox1->Items->Objects[ComboBox1->ItemIndex];
// 將 ComboBox1->ItemIndex 去除
ComboBox1->Delete(ComboBox1->ItemIndex);
// 將 ComboBox1->ItemIndex 對應的 TMyForm 自記憶體移除
delete NeedDelete;
[/code]
善用 TStrings 您就不必使用 TMyForm *Im[20]; 這種固定陣列的方式,也才能真的作到「動態」,
不然,若動態增加大於 20 時,原宣告就不夠用了。
TStrings->Objects 之應用,在本站應該也可以找到許多應用的 Post,這算是很常用的技巧。


強力推薦 ShareMe 免費網路硬碟 VMASK VMIO-Server/SECS/GEM dllee's blog dllee's StatPlus
------
http://www.ViewMove.com
sugizo656
一般會員


發表:6
回覆:8
積分:2
註冊:2005-08-02

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-09-16 13:44:14 IP:59.112.xxx.xxx 訂閱
超感謝!!..說的好清楚!...但現在卻沒辦法test..明天test過後會來結案低^_^
sugizo656
一般會員


發表:6
回覆:8
積分:2
註冊:2005-08-02

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-09-17 10:18:46 IP:220.130.xxx.xxx 訂閱
您好:
再請教一個問題

在上文中我使用TMyForm *Im[20];
是因為程式必須在使用者的選擇下(ex: 在combobox內選擇Form5, Form9) , 去取子視窗下的成員物件
再按下一個Button後
將Form5, Form9下的成員物件執行一段計算
但因為編譯器無法使用Form[combobox1->ItemIndex] , Form[combobox2->ItemIndex]去執行
所以沒辦法用固定的名稱去命名子視窗
因此選擇用物件陣列*Im[20]的方式來宣告,才有index能用
請問前輩是否有更好的方式是我沒想到的呢?
sugizo656
一般會員


發表:6
回覆:8
積分:2
註冊:2005-08-02

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-09-17 12:01:55 IP:220.130.xxx.xxx 訂閱
sorry
我是有疑問>"<
假設我用AddObject新增字串和對應的Form後
當按下COMBOBOX的Click,
要怎麼利用COMBOBOX所被按下字串,來讓對應的Form->show?
不是利用Form[COMBOBOX->itemindex]->show喔!!
因為當某個Form刪除(COMBOBOX下的item也一併刪除)時
itemindex所對應的Form就不是原先的順序

例如:
[code cpp]
//加入item
ComboBox1->Items->AddObject("AA",Im[0]);
ComboBox1->Items->AddObject("BB",Im[1]);
ComboBox1->Items->AddObject("CC",Im[2]);
[/code]


[code cpp]
//刪掉第二個item
void __fastcall TConvolution_From::Button1Click(TObject *Sender)
{
Im[1]->close();
ComboBox1->Items->Delete(1); //刪掉"BB"
}

[/code]

此時再click ComboBox中的"CC"時
利用Im[ComboBox->itemindex]->show();
就會去show已經free掉的Im[2]而造成錯誤!

所以有沒有能用字串"CC"去開啟它對應的Form
我看bcb的help檔是說: AddObject returns the index of the new string and object.
可是我不要index阿~~~index會在某個item刪除掉後順序亂掉


我查詢相關文章總覺得沒有我要的
麻煩請大大提供一些相關文章

編輯記錄
sugizo656 重新編輯於 2007-09-17 13:21:34, 註解 無‧
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-09-17 12:43:27 IP:220.134.xxx.xxx 訂閱
所以,您還是不了解如何使用 Objects 

之前提供的使用範例在 Delete 的部分是否有看到如何取出所選擇項目的表單指標呢?
同樣的方法用在 OnClick 事件,取出點選項目對應的表單。
您的 #4, #5 的問題是一樣的,請您再試試吧。



強力推薦 ShareMe 免費網路硬碟VMASKVMIO-Server/SECS/GEMdllee's blogdllee's StatPlus
------
http://www.ViewMove.com
sugizo656
一般會員


發表:6
回覆:8
積分:2
註冊:2005-08-02

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-09-17 13:31:25 IP:220.130.xxx.xxx 訂閱
dllee大大:

不好意思~~我#5的問題更新過了
請問仍是照你說的方法解決嗎?

dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#8 引用回覆 回覆 發表時間:2007-09-17 14:02:08 IP:220.134.xxx.xxx 訂閱
[code cpp]
// 顯示目前選到的 Item 對應視窗
void ShowCurrentIndexForm(void)
{
TMyForm *CurrentSelect=(TMyForm*)ComboBox1->Items->Objects[ComboBox1->ItemIndex];
CurrentSelect->Show();
}

// 顯示指定 Item 對應視窗(請自行加入 Index 範圍判斷 基本的 ComboBox 使用或 TStrings 應用)
void ShowFormByIndex(int index)
{
TMyForm *FormIndex=(TMyForm*)ComboBox1->Items->Objects[index];
FormIndex->Show();
}

// 刪除指定的 Item 對應視窗
void DeleteCurrentIndexForm(void)
{
TMyForm *CurrentSelect=(TMyForm*)ComboBox1->Items->Objects[ComboBox1->ItemIndex];
ComboBox1->Delete(ComboBox1->ItemIndex);
delete CurrentSelect;
}

// 顯示指定 Item 對應視窗(請自行加入 Index 範圍判斷 基本的 ComboBox 使用或 TStrings 應用)
void DeleteFormByIndex(int index)
{
TMyForm *FormIndex=(TMyForm*)ComboBox1->Items->Objects[index];
ComboBox1->Delete(index);
delete FormIndex;
}
[/code]
我所說的方法是不用 lm[ ] 的,如果您要使用 lm 請使用其他的方式,不然等於是雞同鴨講。

請您先作 TStrings 之 Strings 及 Objects 操作練習,如果無法習慣(或無法接受) Objects 操作,
只能說,您的練習不夠,除了多練習,我也無法再作進一步的說明。

如同,學英文,背單字,單字是會背了沒錯(Objects[] 看懂了),但是不知道例句是什麼意思,
自然不會用這個單字在句子上。只能多說說這些例句,試著了解用法,才能用在一般的句子上。
如果您要我把此單字可能的例句都說給您聽,那我... 沒這個能力


強力推薦 ShareMe 免費網路硬碟VMASKVMIO-Server/SECS/GEMdllee's blogdllee's StatPlus
------
http://www.ViewMove.com
sugizo656
一般會員


發表:6
回覆:8
積分:2
註冊:2005-08-02

發送簡訊給我
#9 引用回覆 回覆 發表時間:2007-09-17 16:09:34 IP:220.130.xxx.xxx 訂閱
dllee大大:
謝謝你的解說!
我大概了解了
也更確認我只能在index上下大量的功夫
因為我的需求是開啟大量的Form(每個Form下各有一張影像)並靈活運用,似乎還是得用物件陣列Im[20]
與其在index上用大量的for和if_else if..去排列新的順序
還不如另外用個矩陣S複製combobox所加入過的檔案名稱字串
按下combobox的click時,讀取被選取的字串來比對矩陣S
就能知道該Form原本的index
進而show出該Form

唉..本來以為Addobject能直接透過字串操作object
例如:
Addobject(AnsiString,TObject)
GetObject(AnsiString)而不是GetObject(int index);
沒想到還是Combobox->items->objects[index]去操作


謝謝您上面的教學~~
也讓我知道TMyForm *FormIndex=(TMyForm*)ComboBox1->Items->Objects[index]; 的用法
對我還是助益很大
編輯記錄
sugizo656 重新編輯於 2007-09-17 16:24:31, 註解 無‧
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#10 引用回覆 回覆 發表時間:2007-09-17 17:22:05 IP:220.134.xxx.xxx 訂閱
我了解了,再增加兩個函式給您參考,您會更了解 TStrings 的用法。

[code cpp]
// 顯示指定 名稱(Strings[ ]) 所對應的視窗
void ShowFormByItemName(AnsiString ItemName)
{
int index=ComboBox1->Items->IndexOf(ItemName);
if(index>=0) // 在列表內
{
TMyForm *FormIndex=(TMyForm*)ComboBox1->Items->Objects[index];
FormIndex->Show();
}
else // 不在列表內
{
ShowMessage(ItemName " Not Found!!");
}
}

// 刪除指定 名稱(Strings[ ]) 所對應的視窗 及其 Item
void DeleteFormByItemName(AnsiString ItemName)
{
int index=ComboBox1->Items->IndexOf(ItemName);
if(index>=0) // 在列表內
{
TMyForm *FormIndex=(TMyForm*)ComboBox1->Items->Objects[index];
ComboBox1->Delete(index);
delete FormIndex;
}
else // 不在列表內
{
ShowMessage(ItemName " Not Found!!");
}
}
[/code]




強力推薦 Seednet ShareMe 至少 2G 免費網路硬碟, 最大特點:放檔後不使用不會砍檔
------
http://www.ViewMove.com
sugizo656
一般會員


發表:6
回覆:8
積分:2
註冊:2005-08-02

發送簡訊給我
#11 引用回覆 回覆 發表時間:2007-09-17 21:26:28 IP:220.130.xxx.xxx 訂閱
  感謝大大又提供了新的函式用法!!
我已經運用上面所得之資訊和想法解決了我的問題:)
系統時間:2024-04-27 13:01:08
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!