2011-01-06 39 views
8

Tôi đang cố gắng theo dõi nguyên nhân gây ra lỗi giao diện gây phiền nhiễu trong một ứng dụng gần đây đã được nâng cấp từ VS2003 lên VS2008 (lỗi không tồn tại trước khi di chuyển). Điều gì xảy ra là:Không thể thoát khỏi hộp văn bản trống

1) Nhấp chuột của người dùng trong hộp văn bản chứa ngày.
2) Người dùng xóa ngày
3) Người dùng cố di chuyển đến một trường khác, nhưng không thể. Không có thông báo lỗi xuất hiện - nó như thể xác thực không thành công.

thông tin bổ sung:

1) thuộc tính Text của textbox được ràng buộc với một dataview trong đó sử dụng một DataTable như nguồn của nó. Trường bị ràng buộc là trường datetime không có giá trị không có ràng buộc hoặc mặc định.
2) Sự kiện xác thực cháy và thuộc tính CancelEventArgs không được đặt thành Hủy. Các sự kiện Validated, LostFocus và Leave đều bị cháy, đi LostFocus> Leave> Validating
3) Tôi không thể thấy bất kỳ thay đổi mã nào liên quan đến kiểm soát hoặc nguồn dữ liệu với một vài ngoại lệ. Thứ nhất là điều này:

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

hiện đã thay đổi như thế này:

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

Thứ hai là điều này:

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

hiện đã thay đổi như thế này:

Me.dcolRangeEnd.DataType = GetType(Date) 

Ngoài ra còn có điều này, đã có trong đang kể từ ngày đầu tiên:

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 

Bây giờ, nếu tôi loại bỏ các "True" từ thêm các liên kết dữ liệu sau đó tôi có thể thoát khỏi sự kiểm soát với một giá trị trống, nhưng sau đó nó lại trở về giá trị ban đầu. Việc xóa định dạng ngày xuất hiện để không tạo ra sự khác biệt về điều này (nó chỉ hoàn nguyên để hiển thị ngày 06/01/2011 00:00:00 thay vì ngày 06/01/2010 mong muốn). Không có mã nào khác đề cập đến hộp văn bản đó. Tôi đang nghĩ một cái gì đó phải có thay đổi trong xác nhận điều khiển databound giữa VS2003 và VS2008, nhưng nó chỉ là khả năng tôi thiếu một cái gì đó tâm-numbingly rõ ràng.

Bất kỳ ý tưởng nào?

Trả lời

7

Lý do bạn thấy hành vi được quan sát là làm thế nào với Windows Forms và Binding dữ liệu của nó xử lý các giá trị cơ sở dữ liệu NULL.

Các TL;DR lý do:

Xem gợi ý này Microsoft Connect: Provide better databinding support for nullable types

Phiên bản dài:

gì là chủ yếu xảy ra là khi bạn xóa các Textbox (để một sản phẩm nào chuỗi) và sau đó tab đi, ràng buộc là chuyển đổi chuỗi rỗng của bạn thành một giá trị DBNull mà sau đó được truyền cho nguồn dữ liệu tuy nhiên ràng buộc, vì nó là hai -way, sau đó cố gắng nhập lại điều khiển bị ràng buộc (Hộp văn bản) với định dạng thích hợp và không thành công, khiến Hộp văn bản hiển thị hành vi kỳ lạ của việc không cho phép tiêu điểm được xóa khỏi nó!

Điều này xảy ra do thuộc tính DataSourceNullValue của Binding class. Điều này có thể được thiết lập bằng cách sử dụng một trong các quá trình xây dựng lớp Binding, hoặc thiết lập riêng thông qua một thiết lập thuộc tính, tuy nhiên, nếu bạn không thiết lập rõ ràng thuộc tính này, điều quan trọng cần lưu ý là:

Giá trị mặc định là DBNull các loại giá trị và null cho các loại không có giá trị.

Dường như bạn không đặt rõ điều này, vì vậy mặc định đang áp dụng và với DateTime là value type, sử dụng DBNull.

Khi nguồn dữ liệu đã được cập nhật (để DBNull), cơ chế ràng buộc sẽ cố gắng sau đó điền lại Hộp văn bản với giá trị nguồn dữ liệu mới được cập nhật. Khi giá trị nguồn dữ liệu cơ bản là DBNull, giá trị được sử dụng cho điều khiển biên được điều chỉnh bởi lớp NullValue property của lớp Binding. Một lần nữa, nếu tài sản này không được rõ ràng thiết lập hoặc thông qua đối số nhà xây dựng quá tải có liên quan hoặc thông qua bất động sản thiết lập chính nó, giá trị mặc định sẽ được áp dụng, đó là:

Các đối tượng được thiết lập như là sự kiểm soát tài sản khi nguồn dữ liệu chứa giá trị DBNull. Giá trị mặc định là null.

Tất nhiên, một Textbox's Text property chỉ có thể được thiết lập để một đối tượng kiểu System.String và không phải là một giá trị null (Không có gì trong VB), vì vậy các TextBox không ràng buộc giá trị đại diện (null/gì) của dữ liệu giá trị của nguồn (DBNull) tới điều khiển biên.

Cách khắc phục hành vi này là đảm bảo rằng Binding class's NullValue property được đặt rõ ràng thành giá trị phù hợp. Trong trường hợp này, một chuỗi có độ dài bằng không sẽ đủ để sửa vấn đề.

Một cách để đạt được điều này là thay đổi dòng:

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

tới:

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

Mấu chốt ở đây là tham số cuối cùng, đó là NullValue, thiết lập để một zero- chuỗi dài (The DataSourceUpdateMode cũng được chỉ định rõ ràng do các đối số của hàm tạo, nhưng nó vẫn được đặt thành giá trị mặc định của nó).

Mặc dù tất cả điều này, có vẻ như hành vi hơi "lạ", nếu không phải là lỗi thực sự. Điều này cũng được chứng minh bởi những người khác dường như đang gặp vấn đề tương tự (vẫn còn phổ biến trong Visual Studio 2010/.NET 4.0!). This thread trên diễn đàn social.msdn.microsoft.com chứa người nào đó gặp sự cố tương tự với một số giải thích thú vị có thể giải thích tại sao điều này xảy ra và tại sao Microsoft thiết kế theo cách này.

Ngoài ra còn có Microsoft Connect suggestion đã được báo cáo lại vào năm 2005 nêu bật vấn đề. Đề xuất này đã được "Đóng thành Đã hoãn". Có vẻ như Microsoft không coi đó là một lỗi, vì một giải pháp rất hợp lý tồn tại (thiết lập rõ ràng của thuộc tính NullValue của Binding), được cho là nên được thực hiện cho mục đích dễ đọc. Họ rõ ràng sẽ xem xét đề xuất trong tương lai.

Quay lại lý do tại sao điều này không tồn tại trước.NET 2.0 (Visual Studio 2005) có vẻ là do thực tế rằng toàn bộ cơ chế ràng buộc dữ liệu đã được tân trang lại hoàn toàn cho việc phát hành .NET Framework 2.0. Giải pháp ban đầu của bạn, là một dự án VS2003 đang sử dụng .NET Framework 1.1, không có bộ tính năng ràng buộc dữ liệu phong phú. Mặc dù tôi không còn có bản sao của VS2003 để kiểm tra điều này nữa, tôi giả sử cơ chế ràng buộc trong .NET 1.1 đã sử dụng nhiều hơn ẩn số chuyển đổi giữa giá trị của điều khiển và giá trị của nguồn dữ liệu. Điều này xuất hiện để được hỗ trợ khi bạn kiểm tra lớp Binding từ .NET 1.1, so với .NET 2.0 (hoặc cao hơn). Ví dụ, không có cách nào để (dễ dàng) kiểm soát bản thân ràng buộc hai chiều thực tế (và cách các giá trị được chuyển đổi giữa biểu mẫu và nguồn dữ liệu) hoặc định dạng các giá trị đã nói.

+0

Phương thức FormatBoxToDate nhỏ đó thực sự được tạo vì .NET 2003 không có cách nào khác để thực hiện. Thuộc tính giá trị null bây giờ có thể truy cập thông qua menu Databindings nâng cao - tuy nhiên, cố gắng thiết lập nó thành một chuỗi rỗng bằng cách sử dụng IDE thực sự đặt giá trị thành Nothing (Không có gì trong mã) ... điều này không tạo ra sự khác biệt nào. – MartW

+0

Tôi đã tự tay hack nó vào String.Empty (không bao giờ thích đặt "") và nó bây giờ hoạt động. Tôi gọi đó là tiền thưởng kiếm được: D – MartW

+0

Rất cũ, nhưng rất hữu ích vì nó vẫn được áp dụng trong VS2013! nhưng câu hỏi phụ: dòng để thay đổi làm việc tuyệt vời cho tôi .. nhưng tôi có mọi thứ khác được duy trì trong các thuộc tính thiết kế .. nếu tôi hiểu nó đúng, đó là một vấn đề thêm giá trị null trong sau theo thuộc tính hộp văn bản -> (Data Bindings) -> (Advanced) -> chọn thuộc tính text, chọn định dạng ngày tháng (trong trường hợp của tôi), sau đó điền vào giá trị null. Tuy nhiên, một chuỗi rỗng dường như không hoạt động ở đó. bất kỳ lời khuyên nào về cách làm điều đó trong nhà thiết kế? –

0

Tôi đã có loại lỗi này trước và tôi phải đảm bảo rằng nguồn dữ liệu cơ bản (trong trường hợp của tôi là tập dữ liệu) không được đặt thành chỉ đọc và cột cho phép giá trị `null '.

Khi tôi đã làm tất cả mọi thứ này hoạt động tốt. Dường như lỗi bị ném vào Data Bindings bị nuốt chửng ở đâu đó và không lan truyền.

Các vấn đề liên quan