2013-02-14 56 views
3

想用發件人的TObject的爲我的情況下,選擇標準...語句發件人作爲TObject的對於事例......與德爾福

procedure TForm.ShowGUI (Sender: TObject); 
begin 
    case sender of 
     ToolButton1: begin 
      do_something;   
     end; 

     ToolButton2: begin 
      /// 
     end; 

     ToolButton3: begin 
      do_stufff_here; 
     end; 

     ToolButton3: begin 
      /// 
     end; 

     else ; 

    end; 
end; 

的技巧,使發送方序類型案件陳述要求?

+0

一招是創建行動,以顯示不同的圖形用戶界面的類型,並指定每個動作都能正確的按鈕 – idursun 2013-02-14 08:06:36

+0

這是關於時間,德爾福將開始更加靈活的有關'案例'聲明。他們*可以*自動將case語句轉換爲幕後的一系列'if'語句,從而允許我們使用非常量表達式和字符串。無論如何我們會這樣做,這樣可以節省我們的體力勞動。 – 2013-02-14 09:02:52

+0

@Cosmin:一年前在EMBA論壇上討論了Delphi中的模式匹配,Nick Hodges(如果我的記憶服務於我)甚至將其作爲Delphi II語言的可能性。 – 2013-02-14 11:02:19

回答

10

您可以輕鬆地將其轉換爲一個整數(例如轉換Sender到一個序:NativeUInt(Sender) - 而是因爲case聲明預計的「分支」常量表達式會做你沒有好,和​​.. ToolButton3 AREN 「T常數,它們是變量

例如,您可以在按鈕的屬性來完成的情況下,例如,給每個ToolButton一個Tag屬性,它是有意義的,那麼你可以做這樣的事情:

case (Sender as TToolButton).Tag of 
    1: ; // ToolButton1 was pressed 
    2: ; // ToolButton2 was pressed   
end; 

正如David所建議的:除非您使用的控件具有直接與其功能直接相關的屬性(非常不可能),否則簡單的鏈式if語句可能更易於閱讀。我的第一個建議中的Tag屬性需要專門配置,而這只是引入錯誤的其他方法。例如:也許你複製粘貼一個按鈕,但忘記改變它的標籤,你現在有兩個標籤相同的按鈕。

首先,您應該重命名代碼中使用的所有組件,併爲其指定專用名稱。然後你可以這樣寫:

if (Sender = tbAlignTextLeft) then 
    begin 
    // The tool-button for left text alignment was pressed 
    end 
else if (Sender = tbAlignTextCenter) then 
    begin 
    // Center-alignment button was pressed 
    end 
else 
    begin 
    // This would be the default action. If it were me, I'd raise an exception here. 
    end 
+2

+1如果你這樣做,我建議你在代碼中設置標籤,而不是在對象檢查器中使用常量而不是數字。這很可能使未來的維護更容易。 – 2013-02-14 08:14:54

+3

雖然你可以這樣做,但if語句會更清晰。 – 2013-02-14 08:22:28

+0

@DavidHeffernan顯然,可能有兩個以上的按鈕,在這種情況下'case'更清潔。 – jpfollenius 2013-02-14 08:23:47

6

考慮添加一些運行時支持來將枚舉與控件相關聯。

首先創建一個枚舉類型:

type 
    TControlID = (cidAlignTextLeft, cidAlignTextRight, ....); 

然後添加一個詞典的形式:

FControlIDs: TDictionary<TControl, TControlID>; 

然後在窗體的構造函數創建和填充字典:

FControlIDs := TDictionary<TControl, TControlID>.Create; 
FControlIDs.Add(tbAlignTextLeft, cidAlignTextLeft); 
FControlIDs.Add(tbAlignTextRight, cidAlignTextRight); 
.... 

這部分代碼應該放置在一個單獨的本地幫助器函數中,而不是內聯你的窗體的構造函數。

現在你可以寫你的case語句:

case FControlIDs[Sender as TControl] of 
cidAlignTextLeft: 
    .... 
cidAlignTextRight: 
    .... 
+0

您可能會將'TControlID'填充到'Tag'中,爲case語句將'Tag'轉換爲'TControlID'。幾乎相同減去字典查找。 – 2013-02-14 08:59:46

+1

@CosminPrund我對'Tag'有強烈的厭惡感。使用它會讓我感覺很髒。就像我在VB6中編寫的一樣。如果你忘記爲其中一個控件分配'Tag',那麼它默認爲'cidAlignTextLeft'! – 2013-02-14 09:01:34

+0

把一個'cidUnassigned'作爲第一個枚舉元素來防止這種情況發生。 – 2013-02-14 09:10:26