這鳥屬性把我害苦過,特此敬告一下大家。具體表現在:
獲取時:在DateTimePicker.ValueChanged事件中,獲取到的Text有可能是string.Empty!!!,特別當ValueChanged事件是在構造函數或Load、Shown等啟動事件中觸發時,得到string.Empty的幾率增大;
賦值時:有可能觸發不了TextChanged事件(該事件默認不顯示在設計器中,但的確是存在的);
可能的原因:先看Value屬性的setter源碼:
set { bool flag = !DateTime.Equals(this.Value, value); if (!this.userHasSetValue || flag) { if ((value < this.MinDate) || (value > this.MaxDate)) { throw new ArgumentOutOfRangeException("Value", SR.GetString("InvalidBoundArgument", new object[] { "Value", FormatDateTime(value), "'MinDate'", "'MaxDate'" })); } string text = this.Text; this.value = value;//修改value this.userHasSetValue = true; //判斷是否擁有句柄 if (base.IsHandleCreated) { int wParam = 0; NativeMethods.SYSTEMTIME lParam = DateTimeToSysTime(value); //發送消息:有可能就是這廝負責改Text UnsafeNativeMethods.SendMessage(new HandleRef(this, base.Handle), 0x1002, wParam, lParam); } if (flag) { this.OnValueChanged(EventArgs.Empty);//觸發ValueChanged事件 } if (!text.Equals(this.Text)) { this.OnTextChanged(EventArgs.Empty); } } }
當中沒有直接對this.Text賦值,這應該是為了避免陷入死循環,因為Text改變也會觸發Value改變,也可能正因為這樣,MS采取了迂回的方式來處理Text屬性——通過Windows消息機制,而該機制是依賴控件句柄的,換言之只有當控件擁有了句柄才能處理Text。對消息機制和控件句柄我不熟(玩Win32開發的童鞋們那就相當的熟了),我猜控件句柄的生成和分配由OS負責,分配時機也不一定,大概可能是控件顯現了才會分配到。所以在構造函數或Load、Shown等啟動事件中修改Value時,也許控件還未分配到句柄,所以Text未被處理,導致得不到正確結果~
上述均是猜的哦,有可能對有可能不對。
所以,無論如何,敬告大家,對於DateTimePicker控件,Value和ValueChanged才是你正確的選擇,忘掉Text和TextChanged。