2013-07-15 67 views
1

我設置TSpinEdit的MaxValue的100000,但是當我運行它,它讓我輸入100000值,如果我手動輸入(而不是使用自旋)。 有什麼辦法可以在不寫代碼的情況下將值限制爲MaxValue?否則,MaxValue屬性是100%無用的。如何防止用戶輸入超過TSpinEdit.MaxValue的值?

的問題是,當用戶進入一個巨大的價值這讓因爲BigFileThreshis紅衣主教的RageCheckError。

procedure TFrmMain.spnMaxFileSizeChange(Sender: TObject); 
begin 
PlaylistCtrl.BigFileThresh:= spnMaxFileSize.Value * KB; 
end; 

這種新TSpinEdit 的行爲可能會導致德爾福計劃,在很多地方崩潰。我更喜歡Delphi 7中的那個。

這將是容易的當前形勢下添加這樣一行:

if spnMaxFileSize.Value> spnMaxFileSize.MaxValue 
then spnMaxFileSize.Value:= spnMaxFileSize.MaxValue; 

但是從現在開始加入這行,或者打開我的所有程序,並加入這一行?這太瘋狂了!

+0

@TLama - 我更新了問題。你現在會看到問題。 – Ampere

+0

我不明白它是如何100%無用的。它仍然可以防止使用旋鈕時數字太高,不是嗎? –

+0

好的。 50%是無用的,因爲50%的用戶(可能更多?)將手動輸入值。 – Ampere

回答

0

像這樣的事情

TYPE 
TMySpinEdit = class(TSpinEdit) { Fixes the OnChange MinValue/MaxValue issue. Details here: http://stackoverflow.com/questions/17655854/how-do-i-prevent-users-from-entering-values-that-exceed-tspinedit-maxvalue/17656652#17656652 } 
    private 
    Timer: TTimer; 
    FOnChanged: TNotifyEvent; 
    procedure TimesUp(Sender: TObject); 
    public 
    constructor Create (AOwner: TComponent);override; 
    destructor Destroy;override; 
    procedure Change; override; 
    published 
    property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; 
end; 



constructor TMySpinEdit.Create(AOwner: TComponent); 
begin 
inherited; 
Timer:= TTimer.Create(Self); 
Timer.OnTimer:= TimesUp; 
Timer.Interval:= 2500; { allow user 2.5 seconds to enter a new correct value } 
end; 

destructor TMySpinEdit.Destroy; 
begin 
FreeAndNil(Timer); 
inherited; 
end; 

procedure TMySpinEdit.Change; 
begin 
Timer.Enabled:= FALSE; 
Timer.Enabled:= TRUE; 
end; 

procedure TMySpinEdit.TimesUp; 
begin 
Timer.Enabled:= FALSE; 

if (MaxValue<> 0) AND (Value> MaxValue) 
then Value:= MaxValue; 

if (MinValue<> 0) AND (Value< MinValue) 
then Value:= MinValue; 

if Assigned(FOnChanged) 
then FOnChanged(Self); 
end; 

代碼尚未測試(被編譯)。我不得不使用我自己的OnChanged事件。將所有這些東西放在OnChange事件中將會很好。任何想法如何做到這一點?這樣,在所有項目(PAS和DFM)上應用批量替換將變得更加容易。

(來吧內河碼頭;它不那麼難)

+1

呃......在使用RxSpinEdit(現在是http://jvcl.sf.net的一部分)工作了一段時間之後,我可以說你並不是無用的,而是一種危險和破壞性的東西。 MAX的成像設置爲20000,entereg值爲10000.用戶希望將其更改爲10500--這是一個合法的選擇。他將curson放在文本中間並鍵入「5」。然後他鍵入「Del」刪除一個額外的零字符。然後他發現自己在EMPTY edt框前面,因爲當他鍵入「5」時過度激活OnChange殺死了他的輸入並用新的全選「20000」文本取而代之。 「何時數值化」這個問題並不容易。 –

+0

例如,您可能會在失去焦點時嘗試去做。或者什麼時候從'TSpinEdit.AsInteger'或'TSpinEdit.AsFloat'讀取。但是你不應該通過'OnChange'事件去除用戶數據中間的輸入來破壞用戶的數據。 –

+0

如果你想以這種方式去除,你不應該忘記在你的'procedure Change;'中添加override,並且在你的過程結束時調用'inherited'。 – bummi

2

正如您看到的,在SpinEdit的「的onChange」事件將被調用,即使當前輸入的數字超出了範圍。當您將焦點更改爲其他控件時,該值正確限制爲 。

你可以嘗試做TSpinEdit新(衍生)版本,它不以這種方式工作,oryou只需添加所需的檢查,以您的OnChange事件處理程序。

+0

@roddy - 感謝Roddy,我正在與定時器的版本工作。 +1 – Ampere

1

由於唯一的地方校驗值被稱爲是CM_Exit的消息處理程序,你可以使用

procedure TFrmMain.spnMaxFileSizeChange(Sender: TObject); 
begin 
SendMessage(TSpinEdit(Sender).Handle,CM_EXIT,0,0); 
PlaylistCtrl.BigFileThresh:= spnMaxFileSize.Value * KB; 
end; 

才能收到所期望的行爲。

調查.. \源\ WIN32 \樣本\來源。

+0

我們的想法是:1)每次在表單上放置一個新的TSpinEdit時,都會忘記添加此行。2)必須在現有的所有代碼中修復它。使用TGoodSpinEdit批量替換TSpinEdit會更容易(自動)。 – Ampere

+0

此外,該代碼還引入了其他功能問題。無論如何,也請記住這個解決方案。 +1 – Ampere