2013-04-08 57 views
0

我遇到了DateTimePicker的問題,它很容易重現,感覺就像是控件本身的錯誤,但我想確保我不會誤解任何東西。使用DateTimePicker創建一個WinForms應用程序(我們的項目在.net 4.0中,但我嘗試在.net 4.5中創建它,同樣的問題)。選擇器本身具有格式爲「HH:mm」的自定義格式,並且ShowUpDown也設置爲true。 它有一個驗證方法如下:DateTimePicker WinForm:在驗證更新值時錯誤地設置了值

private void dateTimePicker1_Validating(object sender, CancelEventArgs e) 
{ 
    dateTimePicker1.Value = DateTime.Now; 
} 

設置一個斷點在該行上。

請確保在應用程序中有另一個控件,以便您可以標籤出DateTimePicker來觸發驗證。

現在,在程序中導航到DateTimePicker的路徑並在例如小時字段中輸入「202」。這將看起來像你先寫了20,而當你寫第二個「2」時,它現在只是現場的2。

現在標籤出DateTimePicker。這將觸發驗證斷點。請注意DateTimePicker的值現在是如何設置爲20小時的日期。讓該行執行並再次觀看DateTimePicker的值。現在,數值爲02小時,而不是(數字)(而不是(!!)DateTime.Now的值)

因此,在將值設置爲DateTime.Now之後,它將值更改爲之前未完成的值輸入到DateTimePicker 。

這是怎麼回事,有沒有什麼辦法可以解決這個問題?

+0

進出口使用'窗戶8',當它驗證值爲'02'理所應當的,當它它設置成'DateTime.Now'然後將其設置爲當前時間。我不能重新創建這個。 – 2013-04-08 13:11:16

+0

好吧,那麼它必須在Win8中修復,我目前在Windows 7上,並且它很容易重現。 – Joel 2013-04-08 14:37:15

回答

1

我不能重複這個。 Windows版本非常重要,許多常見的控制怪癖在後來的版本中得到修復。我在Windows 8上。

然而,這是一個普遍的問題,這些控件挑剔你在發起事件時對他們做了什麼。他們傾向於在他們發佈事件後運行代碼,這可能會使您所做的事情失效。驗證事件特別棘手,因爲它會引起焦點變化的副作用。如果DTP還沒有得到相同的通知,那麼就有麻煩了。相當典型的事件訂購麻煩。如果您實際上沒有使用「驗證」驗證數據,請支持「離開」事件。

聽起來像一場比賽。這種排序問題的一般解決方案是在之後運行您的代碼事件已經觸發並且代碼執行不再位於控件的代碼中。您可以使用表單的BeginInvoke()方法來優雅地完成任務。目標程序在你的程序重新進入消息循環並且UI回到靜止狀態之後運行。就像這樣:

private void dateTimePicker1_Validating(object sender, CancelEventArgs e) { 
     this.BeginInvoke(new Action(() => dateTimePicker1.Value = DateTime.Now)); 
    } 
+0

我喜歡這個想法,在驗證事件之後運行我的buissnes邏輯,但它在我的生產代碼中仍然存在一些怪癖。在驗證時,值是「20」,所以我的驗證通過了,但是當BeginInvoke發生的事件觸發時,它已經在GUI和它的值中變成了「02」,這對我的快樂不會有好處 - 邏輯,期望值在一定範圍內。我在Windows 7上。 – Joel 2013-04-08 14:21:41

0

在驗證事件期間,我看到您解釋的行爲,但驗證事件完成後,該值設置爲DateTime.Now

假設你希望它的驗證事件本身期間DateTimePicker控件的值設置爲DateTime.Now,我發現,設置值的兩倍顯示更改爲DateTime.Now值 -

dateTimePicker1.Value = DateTime.Now;

dateTimePicker1.Value = DateTime.Now;

+0

是的,我已經注意到了這一點,這是我的備份解決方法,但代碼本身不是很乾淨,也很混亂。 :) – Joel 2013-04-08 12:27:42