2017-03-23 167 views
0

我真的很困惑。我想要做的事情(看起來非常簡單)是在TDateTimePicker中顯示一個日期+時間,集成日曆,並且可以在其值更改後讀取它。如何從TDateTimePicker讀取日期和時間

我想使用dd/MM/yyyy hh:mm格式。

由於的TDateTimePicker不是TDateOrTimePicker,一個用於一個具有:

  • 種類:dtkDate(顯示日曆)
  • 格式: 'DD/MM/YYYY HH:MM'

看起來不錯,現在讓我們閱讀:

showmessage(DateTimeToStr(DateTimePicker1.Date)); 

只有正確地顯示日期。 hh:mm部分的更改未被考慮。我總是得到默認值。 然後我想:還有一個時間屬性,也許我需要讀取2次的值。

showmessage(DateTimeToStr(DateTimePicker1.Time)); 
showmessage(DateTimeToStr(DateTimePicker1.Date)); 

但我有和以前一樣的輸出(和問題)。所以現在,讓我們嘗試將此Kind屬性更改爲dtkTime,然後讀取時間,然後將其切換回dtkDate,然後讀取日期。

但是不,它仍然不起作用。將Kind屬性從dtkDate切換到dtkTime會在hh:mm部分上刪除我的輸入。


我知道我實際上應該使用2 TDateTimePicker:一個爲日期,一個爲時間。

所以我的問題是:

  • 有一種簡單的方法來解決我的簡單,很常見的問題(一 真正的DateTimePicker)?

而德爾福的設計問題:

  • 爲什麼會出現,基本上是無用的, 誤導格式屬性?有一個TimeFormat,DateFormat和適當的格式 驗證過程並不困難。

請注意,我發佈這個問題主要是爲了避免初學者進行相同的調試和沮喪過程。

+1

好吧,閱讀文檔可能會讓您有一段時間:* TDateTimePicker顯示輸入日期或時間的列表框。*注意**或**。更進一步:*由於TDateTimePicker是Windows控件的包裝,因此不能通過更改SysUtils單元中的格式化變量來更改這些格式。但是,您可以使用Windows API調用DateTime_SetFormat以編程方式指定這些設置。* –

+0

@TomBrunberg是的,我應該在「試圖使其工作」之前看到。我無法從IDE訪問文檔的事實無濟於事。 –

+0

再次,對不起你。你必須以某種方式搞砸你的安裝。我現在特別使用Delphi XE7,並從一個非常實用的幫助文檔中複製文本,直接從IDE訪問。 –

回答

5

我想要做的事情(看起來非常簡單)是在TDateTimePicker中顯示日期+時間,集成日曆,並能夠在其值更改後讀取它。

我想使用DD/MM/YYYY HH:mm格式

很抱歉,但你不能。 A TDateTimePicker被設計爲只能與日期或時間一起使用,但不能同時使用。

如果將Kind屬性設置爲dtkDate,則可以指定自定義DATE格式,但會忽略任何TIME格式,並且使用Time屬性未定義。

如果將Kind屬性設置爲dtkTime,則可以指定自定義TIME格式,但會忽略任何DATE格式,並且使用Date屬性未定義。

當閱讀Date屬性時,只有該值的DATE部分有效。在完美的世界中,時間部分將始終爲零,但我曾經看到它有時包含垃圾。然而,你可以很容易忽略,使用DateUtils.DateOf()功能:

Value := DateOf(DateTimePicker1.Date); 

Time屬性和值的日期部分同樣的事情。您可以使用DateUtils.TimeOf()函數忽略任何潛在的垃圾:

Value := TimeOf(DateTimePicker1.Time); 

有一種簡單的方法來解決我的簡單,很常見的問題(一個真正的DateTimePicker)?

TDateTimePicker唯一真正的解決方案是使用兩個獨立的TDateTimePicker控件,一個爲其他的時間日期。如果你想顯示TDateTime,只是做相反

Value := DateOf(DateTimePicker1.Date) + TimeOf(DateTimePicker2.Time) 

:這兩個值加在一起需要時您可以結合

DateTimePicker1.Date := DateOf(Value); 
DateTimePicker2.Time := TimeOf(Value); 

否則,找到一個第三方選擇器(或寫你自己的)支持你所需要的。

爲什麼有一個Format屬性基本上是無用的和誤導?

這不是無用和誤導。這是非常有用的,但僅限於當前的Kind設置範圍內。

擁有TimeFormat,DateFormat和正確的格式驗證過程並不困難。

TDateTimePicker只是一個Win32的薄包裝器Date and Time Picker control,它沒有這樣的功能。當然,他們可能已寫入自定義邏輯,以允許切換Kind值與不同的設置保存,但這不是真的如何使用DTP控件。您設置了Kind一次,Format一次,然後根據需要處理輸入和輸出。沒有來回切換。只因爲你可以動態切換Kind並不代表你應該。如果您認爲編寫這種自定義邏輯非常簡單,歡迎您使用自己的代碼進行編寫。

1

這幾天我也有同樣令人沮喪的問題。但在我的情況下,我只需要從TDateTimePicker字段獲取完整的日期和時間(不需要以編程方式設置它,但它不會很困難)。所以我做的是創建我自己的TDateTimePicker並創建一個新的公共屬性,獲取字段Caption並設置爲DateTime(Caption受保護的accordind爲documentation)。這是我的代碼:

unit uZDateTimePicker; 

interface 

uses 
Vcl.ComCtrls, SysUtils; 

type 
    TZDateTimePicker = class(TDateTimePicker) 
    private 
    procedure SetDateAndTime; 

    protected 
    procedure Change; override; 

    end; 

implementation 

{ TZDateTimePicker } 

procedure TZDateTimePicker.Change; 
begin 
    SetDateAndTime 
end; 

procedure TZDateTimePicker.SetDateAndTime; 
begin 
    DateTime := StrToDateTime(Caption); 
    inherited; 
end; 


end. 

就這麼簡單。另外,如果你使用DevExpress組件,你可以使用TcxDateEdit,它可以像你想要的那樣工作。

0

我有完全相同的問題。 安德烈解決方案像一個魅力,感謝安德烈)。

問題:我們需要創建一個新單元,創建一個新組件並將該組件註冊到另一個包中,以便能夠在設計時設置該表單。

解決方法:要避免這種情況,只是在形式申報,你正在使用的TDateTimePicker組件下面的類:THackDateTimePicker

... 
type 
    // this class is just to access protected Caption property 
    THackDateTimePicker = class(TDateTimePicker); 

    TSymbolInfoForm = class(TForm) 
    ... 
end; 

然後,只需執行OnChange事件,如:

procedure TSymbolInfoForm.dtpChange(Sender: TObject); 
begin 
    TDatetimePicker(Sender).Datetime := StrToDateTime(THackDateTimePicker(Sender).Caption); 
end; 

可以鏈接所有TDateTimePicker組件上的所有OnChange事件都在同一個窗體上,並保持原樣的OnChange事件...並且瞧!