簡體   English   中英

無法轉義空文本框

[英]Can't escape empty textbox

我正在嘗試追蹤最近從VS2003升級到VS2008的應用程序中令人討厭的界面錯誤的原因(錯誤在遷移前不存在)。 這是怎么回事:

1)用戶在包含日期的文本框中單擊。
2)用戶清除日期
3)用戶嘗試移動到另一個字段,但不能。 沒有出現錯誤消息 - 就像驗證失敗一樣。

更多信息:

1)文本框的Text屬性綁定到使用數據表作為其源的數據視圖。 綁定字段是可空的日期時間字段,沒有約束或默認值。
2)Validating事件觸發,CancelEventArgs屬性未設置為Cancel。 Validated,LostFocus和Leave事件也都會激活,進入LostFocus> Leave> Validating
3)除了幾個例外,我看不到任何與控件或數據源相關的代碼更改。 首先是這個:

Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd"))

現在改為:

Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd", True))

第二是這個:

Me.dcolRangeEnd.DataType = GetType(System.DateTime)

現在改為:

Me.dcolRangeEnd.DataType = GetType(Date)

還有這個,從第一天開始就在代碼中:

AddHandler txtRangeEnd.DataBindings("Text").Format, AddressOf FormatBoxToDate

Private Sub FormatBoxToDate(ByVal sender As Object, ByVal e As ConvertEventArgs)
Try
    If Not e.Value Is DBNull.Value Then
            e.Value = Format(e.Value, "d")
        End If
    End Try
End Sub

現在,如果我從添加數據綁定中刪除“,True”,那么我可以使用空值退出控件,但它會恢復為原始值。 刪除日期格式似乎沒有區別(它只是顯示06/01/2011 00:00:00而不是所需的06/01/2010)。 根本沒有其他代碼引用該文本框。 我認為VS2003和VS2008之間的數據綁定控件的驗證必定會有所改變,但我很可能會錯過一些令人頭腦麻木的東西。

有任何想法嗎?

您看到觀察到的行為的原因與Windows窗體及其數據綁定如何處理NULL數據庫值有關。

TL; DR原因:

請參閱此Microsoft Connect建議: 為可空類型提供更好的數據綁定支持

長版:

本質上發生的是,當您清除文本框(到空字符串)並隨后標簽離開時,綁定正在將空字符串轉換為DBNull值,然后將其傳播到數據源但是綁定,因為它是兩個 -然后,嘗試以適當的格式重新填充綁定控件(文本框),並失敗,導致文本框顯示不允許從中刪除焦點的奇怪行為!

這是由於Binding類DataSourceNullValue屬性而發生的。 這可以使用其中一個Binding類構造函數重載來設置,或者通過屬性設置單獨設置,但是,如果您沒有顯式設置此屬性,請務必注意:

對於值類型,默認值為DBNull,對於非值類型,默認值為null。

看來你沒有明確地設置它,所以默認是應用,並且DateTime是值類型 ,它使用DBNull。

一旦數據源更新(到DBNull),綁定機制將嘗試使用新更新的數據源值重新填充文本框。 當基礎數據源值為DBNull時,用於綁定控件的值由Binding類的NullValue屬性控制 同樣,如果未通過相關的重載構造函數參數或通過屬性設置本身顯式設置此屬性,則將應用默認值,即:

當數據源包含DBNull值時,要設置為控件屬性的Object。 默認值為null。

當然, Textbox的Text屬性只能設置為System.String類型的對象而不是null值(VB中為Nothing),因此TextBox無法綁定數據源值的代表值(null / nothing)( DBNull)到綁定控件。

更正此行為的方法是確保將Binding類的NullValue屬性顯式設置為合適的值。 在這種情況下,零長度字符串就足以糾正問題。

實現此目的的一種方法是更改​​線路:

Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd", True))

至:

Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd", True, DataSourceUpdateMode.OnValidation, ""))

這里的關鍵是最后一個參數,即NullValue,設置為零長度字符串(由於構造函數的參數, DataSourceUpdateMode也被顯式指定,但無論如何它都被設置為默認值)。

盡管如此,如果不是真正的錯誤,它似乎確實有些“奇怪”的行為。 其他似乎遇到同樣問題的人也證明了這一點(在Visual Studio 2010 / .NET 4.0中仍然很普遍!)。 social.msdn.microsoft.com論壇上的這個主題包含遇到同樣問題的人,以及為什么會發生這種情況的一些有趣的可能解釋,以及微軟為何這樣設計它。

還有一個在2005年報告的Microsoft Connect建議突出了該問題。 這個建議已經“暫緩結束”。 似乎微軟並不認為它是一個錯誤,因為存在一個非常合理的解決方法(Binding的NullValue屬性的顯式設置),為了便於閱讀,可以說,無論如何應該這樣做。 他們顯然會考慮將來的建議。

回到.NET 2.0(Visual Studio 2005)之前不存在的原因似乎是因為整個數據綁定機制已經完全針對.NET Framework 2.0的發布進行了改進。 作為VS2003項目的原始解決方案是使用.NET Framework 1.1,它沒有豐富的數據綁定功能集。 雖然我不再需要VS2003的副本來測試它,但我假設.NET 1.1中的綁定機制更多地使用了控件的值和數據源的值之間的隱式轉換。 當您檢查.NET 1.1中的Binding類與.NET 2.0 (或更高版本)相比時,這似乎得到支持。 例如,無法(輕松)控制實際的雙向綁定本身(以及如何在表單和數據源之間轉換值)或所述值的格式。

我以前遇到過這種類型的錯誤,我必須確保底層數據源(在我的情況下是數據集)沒有設置為只讀,並且列允許“null”值。

一旦我完成了這一切,一切正常。 似乎數據綁定中拋出的錯誤被某個地方吞沒了,並沒有傳播開來。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM