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

在FormA讀取FormB裏的text的問題

尚未結案
oktony
中階會員


發表:67
回覆:132
積分:64
註冊:2004-12-05

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-12-22 15:45:51 IP:222.79.xxx.xxx 未訂閱
我需要在FormA的一個button事件把FormB的dbedit.text讀取FormA的lable1,不知怎麽的運行時老會出錯,提示access violation at address XXXXXX.
elvis1000
一般會員


發表:6
回覆:50
積分:16
註冊:2004-12-18

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-12-22 16:07:51 IP:220.134.xxx.xxx 未訂閱
你只要把dbedit所連結的table的欄位值改變,它自己就會跟著變了。 ----------------------- God bless you! I am Dark_Angel.
------
-----------------------
God bless you!
I am Dark_Angel.
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-12-22 16:08:35 IP:220.130.xxx.xxx 未訂閱
你確定FormA在讀取FormB.dbEdit.Text 時,FormB是否已經產生了? FormB是Auto-Create的?
oktony
中階會員


發表:67
回覆:132
積分:64
註冊:2004-12-05

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-12-22 16:22:59 IP:222.79.xxx.xxx 未訂閱
引言: 你確定FormA在讀取FormB.dbEdit.Text 時,FormB是否已經產生了? FormB是Auto-Create的?
沒錯阿FormB是autocreate的,不過我formA是後來showmodal出來的,是否有影響?
deity
尊榮會員


發表:90
回覆:876
積分:678
註冊:2003-05-09

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-12-22 16:47:27 IP:218.15.xxx.xxx 未訂閱
引言:
引言: 你確定FormA在讀取FormB.dbEdit.Text 時,FormB是否已經產生了? FormB是Auto-Create的?
沒錯阿FormB是autocreate的,不過我formA是後來showmodal出來的,是否有影響?
oktony您好: 不知您是以哪个做为MainForm的?这里假设FormB为MainForm,FormB有按钮Button1和Button2;FormA有按钮Button1,下面是范例,对比看看:
uses Unit2;    {$R *.dfm}    procedure TForm1.Button1Click(Sender: TObject);
var
 I : Integer;
begin
  with Query1 do 
    begin
      close;
      sql.Clear;
      sql.Add('select * from "d:\delphi\yj.db"');
      sql.Add('where type="挂号"'); 
      open; 
    end;      DBEdit1.DataSource:=DataSource1;   
  DBEdit1.DataField:='name'
end;    procedure TForm1.Button2Click(Sender: TObject);
begin
  Form2.showmodal;
end;
………………………………………………………………………………
uses Unit1;     {$R *.dfm}    procedure TForm2.Button1Click(Sender: TObject);
begin
  Label1.Caption:=Form1.DBEdit1.Text;
end
运行没问题,试试看 ~~~行径窄处,留一步与人行~~~
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-12-22 16:56:36 IP:220.130.xxx.xxx 未訂閱
這樣看來FormB先於FormA被Create出來, 如此應該沒有問題,你能否Trace一下是哪一 段程式碼出現問題,貼上來看看,比較清楚.
oktony
中階會員


發表:67
回覆:132
積分:64
註冊:2004-12-05

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-12-22 18:37:11 IP:222.79.xxx.xxx 未訂閱
deity的方法在另外一個程序試了一下可以用,但是我這個不知道哪裏有問題,我做的是MDI窗體,formA和formB 2个都是avalible的, FormB是inherited自一個model,是MDIchild,FormB在menu裏面的一個按鈕是這樣創建的:Application.CreateForm(TFormB,FormB); 然後formA是formB的一個按鈕創建出來的。但是雖然2者都是avalible的,可是明明formB已經先被創建出來了,不知錯在哪裏?
oktony
中階會員


發表:67
回覆:132
積分:64
註冊:2004-12-05

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-12-22 18:50:05 IP:222.79.xxx.xxx 未訂閱
剛剛試了一下,如果把formB改成autocreate,並且formstyle改成fsnormal就一切正常了,但是我想要formB必須是avalible而不是autocreate,請問該怎麽辦?謝謝!
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-12-22 19:01:27 IP:220.130.xxx.xxx 未訂閱
先將TFormA及TFormB自Auto-Create Forms List中移至 Available Forms List中. Application.CreateForm(TFormB,FormB); 改為 TFormB.Create(Self);//Self指的是MainForm 然後在
procedure TFormB.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;
[red]確保自TFormB的Create出來的Form Instance在關閉時
釋放記憶體.
在TFormB上用來Create TFormA的按鍵
procedure TFormB.Button1Click(Sender: TObject);
begin
  with TFormA.Create(Self) do//Self指的是TFormB
  try
    ShowMoal;
  finally
    Free;
  end;
end;
TFormA上的按鍵
    procedure TFormA.Button1Click(Sender: TObject);
begin
  if Owner if TFormB then
    Label1.Caption := TFormB(Owner).dbEdit.Text;
end;    
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-12-22 19:17:59 IP:220.130.xxx.xxx 未訂閱
補充說明:    通常動態產生的 Form你不能預期只能產生一個, 其中的觀念,你可以參考我之前討論的這一篇    http://delphi.ktop.com.tw/topic.php?TOPIC_ID=61566 你的程式架構的重點在於各個Form(MainForm, ChildForm-TFormB, Normal ShowMoal Form - TFormA)之間的關係如何去串聯,在這裡我 通常用Owner去做,因為只要透過適當的轉型,就可以交互存取了. 而宣告於各個Unit中的Form 變數 [code] var FormB: TFormB; var FormA: TFormA; 並不必然被使用到.如上例之TFormB的Create動作, 你可以產生多個TFormB的Instance;而這些被產出的 TFormB Instance (All ChildForm)都歸它的Owner(MainForm) 管理,透過MDIChildCount, MDIChildren,ActiveMDIChild,你可以 作用於這些Child Form了. 與你共勉之.< >< >
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-12-22 19:21:46 IP:220.130.xxx.xxx 未訂閱
記得Create TFormB 的 MenuItem 要置於 MainForm 上.
oktony
中階會員


發表:67
回覆:132
積分:64
註冊:2004-12-05

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-12-23 19:21:50 IP:218.86.xxx.xxx 未訂閱
實在是太感謝jow了!!我按您所說的做了,在MainForm的一個menuitem裏把Application.CreateForm(TFormB,FormB);改為TFormB.Create(Self); 可是不知道為什么,一運行會提示FormB已經存在的錯誤,還望指教!
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-12-24 09:31:54 IP:220.130.xxx.xxx 未訂閱
●先將TFormA及TFormB自Auto-Create Forms List中移至
  Available Forms List中.    ●Create TFormB時    procedure TForm1.MenuItem1Click(Sender: TObject);
begin

  不要這樣寫 FormB := TFormB.Create(Self),
  因為我們產生的形態為TFormB的Child Form,
  可能不只一個,雖然這樣寫應該也不會有錯,
  只是,在程式的其他部分,如果always引用變數
  FormB,那麼應該先檢查它是否存在,而且它指向
  的Child Form Instance,經常會變,因為這個變數
  一直被Update;
  
      with TFormB.Create(Self) do
  begin
    //設定新產生的TFormB屬性
    //不要設定它的Name Property
  end;
end;        
oktony
中階會員


發表:67
回覆:132
積分:64
註冊:2004-12-05

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-12-24 12:23:32 IP:218.5.xxx.xxx 未訂閱
我去掉Name Property就能顯示了,但是還是無法傳值啊!實在是很不好意思,我問了這麽多次,我把問題具體化給您看一下。其實我是在frmDepartment的部門主管(dbeManager)旁邊有個speedbutton,按下該button后會彈出frmSelectname,雙擊dbrgid的name列之後就會關閉frmSelectname,返回name到dbeManager,frmSelectname中的姓名是參照frmDepartment裏的dbeCode.text從員工表和部門表中選出該部門下的員工。 frmdepartment的speedbutton代碼如下: dbeManager.Text:=frmSelectName.Select; frmSelectname的代碼如下: uses DataModule, frmDepartment, main; var sName:string; {$R *.dfm} function Select:String; begin with Tselectname.Create(Department) do ShowModal; Result:=sName; end; procedure TSelectName.DBGrid1DblClick(Sender: TObject); begin sName:=tName.FieldByName('name').AsString; Close; end; procedure TSelectName.FormActivate(Sender: TObject); begin sName:=''; end; procedure TSelectName.FormCreate(Sender: TObject); var code:string; begin code:=trim(Department.dbeCode.Text); tName.Close; tName.Parameters[0].Value:=StrToInt(code); tName.open; end; end.
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#15 引用回覆 回覆 發表時間:2004-12-24 14:14:58 IP:220.130.xxx.xxx 未訂閱
OK!我注意到你的TfrmSelectName Class比較適合以
Normal ShowModal Form來呈現,因為它只是用來選取
一個字串值 Name;    因為我無法重建你的專案,所以只就你的Code提出一些
個人的看法.    ●    function Select:String;
begin
  with Tselectname.Create(Department) do
    ShowModal;
  Result:=sName;
end;    //Department只有單一個Form Instance?
//在定義Class時應盡量避免使用Global的物件變數名稱,除非
//你能確認它不是nil而且值醒過程中它指向的物件都在合理的
//控制中.    我覺得定義在TfrmDepartment中,比較好.
並且TfrmDepartment應設為動態產生.
自Auto-Create Forms List 移除.    function TfrmDepartment.Select(DefaultValue: string):String;
begin
  with TSelectName.Create(Self) do //Self為TfrmDepartment;
  try
    Code := Trim(dbeCode.Text);
    SelectedName := DefaultValue;
    if _Open then
    begin
      if ShowModal = mrOk then
        Result:= SelectedName;
      _Close;
    end;
  finally
    Free; 
  end;
end;    ●TfrmSelectName
//元件是模擬用的,與你實際專案應有出入
//純粹謹供參考    type
  TfrmSelectName = class(TForm)
    tName: TADODataSet;
    DBGrid1: TDBGrid;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure DBGrid1DblClick(Sender: TObject);
  private
    procedure SetCode(const Value: string);
    function GetCode: string;
  public
    SelectedName: string;
    function _Open;    //Open tName
    procedure _Close;  //Close tName
    property Code: string read GetCode write SetCode;
  end;    implementation    {$R *.dfm}    procedure TfrmSelectName.FormCreate(Sender: TObject);
begin
  SelectedName := '';
  ModalResult := mrCancel;
end;    procedure TfrmSelectName.FormDestroy(Sender: TObject);
begin
  _Close;
end;    procedure TfrmSelectName._Close;
begin
  if tName.Active then tName.Close;
end;    function TfrmSelectName._Open: Boolean;
begin
  if not tName.Active then tName.Open;
  Result := tName.Active;
end;    function TfrmSelectName.GetCode: string;
begin
  Result := tName.Parameters[0].Value;
end;    procedure TfrmSelectName.SetCode(const Value: string);
begin
  if not tName.Active then
    if Value <> Code then
      tName.Parameters[0].Value:=StrToInt(Value);
end;    procedure TfrmSelectName.DBGrid1DblClick(Sender: TObject);
begin
  if tName.Active then
  begin
    SelectedName := tName.FieldByName('name').AsString;
    ModalResult := mrOk;
    Close;  //Close The Form
  end;
end;    
P.S. 模擬程式碼沒有執行與測試....< >< >
系統時間:2024-11-22 13:15:04
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!