Các phương pháp hay nhất về ràng buộc và xác thực dữ liệu WPF


101

Tôi có một ứng dụng WPF rất đơn giản, trong đó tôi đang sử dụng liên kết dữ liệu để cho phép chỉnh sửa một số đối tượng CLR tùy chỉnh. Bây giờ tôi muốn đặt một số xác thực đầu vào khi người dùng nhấp vào lưu. Tuy nhiên, tất cả những cuốn sách WPF tôi đã đọc đều không thực sự dành không gian cho vấn đề này. Tôi thấy rằng bạn có thể tạo ValidationRules tùy chỉnh, nhưng tôi đang tự hỏi liệu điều này có quá mức cần thiết cho nhu cầu của tôi hay không.

Vì vậy, câu hỏi của tôi là: có một ứng dụng hoặc bài báo mẫu tốt ở đâu đó chứng minh phương pháp hay nhất để xác thực đầu vào của người dùng trong WPF không?

Câu trả lời:


83

Tôi nghĩ rằng cách ưu tiên mới có thể là sử dụng IDataErrorInfo

Đọc thêm tại đây


3
Tôi cũng đã tìm thấy khung công tác Cinch ( cinch.codeplex.com ), bao gồm bản demo xác thực các phương pháp hay nhất trong WPF + MVVM và sử dụng IDataErrorInfo
Mark Heath

3
Trong .NET 4.5, bạn có thể sử dụng INotifyErrorInfo cho phép bạn trả về các đối tượng thay vì chỉ các chuỗi.
Peter

24

Từ tài liệu Các mẫu & Thực hành của MS :

Xác thực dữ liệu và báo cáo lỗi

Mô hình hoặc mô hình chế độ xem của bạn thường sẽ được yêu cầu thực hiện xác thực dữ liệu và báo hiệu bất kỳ lỗi xác thực dữ liệu nào đối với chế độ xem để người dùng có thể hành động để sửa chúng.

Silverlight và WPF cung cấp hỗ trợ để quản lý các lỗi xác thực dữ liệu xảy ra khi thay đổi các thuộc tính riêng lẻ bị ràng buộc với các điều khiển trong chế độ xem. Đối với các thuộc tính đơn lẻ bị ràng buộc dữ liệu với một điều khiển, mô hình chế độ xem hoặc mô hình có thể báo hiệu lỗi xác thực dữ liệu trong bộ thiết lập thuộc tính bằng cách từ chối một giá trị xấu sắp đến và đưa ra một ngoại lệ. Nếu thuộc tính ValidatesOnExceptions trên liên kết dữ liệu là đúng, công cụ liên kết dữ liệu trong WPF và Silverlight sẽ xử lý ngoại lệ và hiển thị một dấu hiệu trực quan cho người dùng rằng có lỗi xác thực dữ liệu.

Tuy nhiên, nên tránh việc ném các ngoại lệ với thuộc tính theo cách này nếu có thể. Một cách tiếp cận thay thế là triển khai các giao diện IDataErrorInfo hoặc INotifyDataErrorInfo trên mô hình xem hoặc các lớp mô hình của bạn. Các giao diện này cho phép mô hình dạng xem hoặc mô hình của bạn thực hiện xác thực dữ liệu cho một hoặc nhiều giá trị thuộc tính và trả về thông báo lỗi cho dạng xem để người dùng có thể được thông báo về lỗi.

Tài liệu tiếp tục giải thích cách triển khai IDataErrorInfo và INotifyDataErrorInfo.


3
Tôi đã lo lắng lúc đầu khi tôi thấy một khuyến nghị ngoại lệ. rất vui khi thấy rằng "việc ném các ngoại lệ với các thuộc tính theo cách này nên được tránh nếu có thể"
kenwarner

22
cũng cần lưu ý rằng một số đoạn mã tại microsoft đã quyết định không đưa INotifyDataErrorInfo vào .net4 mà Chỉ đưa vào silverlight. đó là một nỗi đau ..
aL3891

5
@ al3891- điều này sẽ được sắp xếp trong .NET 4.5- msdn.microsoft.com/en-us/library/…
RichardOD

@ aL3891 Có cách nào thay thế cho INotifyDataErrorInfo bị thiếu không?
AgentKnopf

10

cá nhân, tôi đang sử dụng ngoại lệ để xử lý xác thực. nó yêu cầu các bước sau:

  1. trong biểu thức liên kết dữ liệu của mình, bạn cần thêm "ValidatesOnException = True"
  2. trong đối tượng dữ liệu mà bạn đang ràng buộc, bạn cần thêm trình xử lý DependencyPropertyChanged nơi bạn kiểm tra xem giá trị mới có đáp ứng các điều kiện của bạn hay không - nếu không - bạn khôi phục về giá trị cũ của đối tượng (nếu cần) và bạn ném ngoại lệ.
  3. trong mẫu điều khiển mà bạn sử dụng để hiển thị giá trị không hợp lệ trong điều khiển, bạn có thể truy cập Bộ sưu tập lỗi và hiển thị thông báo ngoại lệ.

mẹo ở đây là chỉ liên kết với các đối tượng bắt nguồn từ DependencyObject. triển khai đơn giản của INotifyPropertyChanged sẽ không hoạt động - có một lỗi trong khuôn khổ, ngăn bạn truy cập vào bộ sưu tập lỗi.


3

Cũng kiểm tra bài viết này . Được cho là Microsoft đã phát hành Thư viện Doanh nghiệp (v4.0) của họ từ các mẫu và thực hành của họ, trong đó họ đề cập đến chủ đề xác thực nhưng chúa biết tại sao họ không bao gồm xác thực cho WPF, vì vậy bài đăng trên blog mà tôi đang hướng dẫn bạn, giải thích những gì tác giả đã làm để điều chỉnh nó. Hi vọng điêu nay co ich!


2

Bạn có thể quan tâm đến ứng dụng mẫu BookLibrary của Khung ứng dụng WPF (WAF) . Nó chỉ ra cách sử dụng xác thực trong WPF và cách kiểm soát nút Lưu khi có lỗi xác thực.


0

Nếu lớp doanh nghiệp của bạn được sử dụng trực tiếp bởi giao diện người dùng của bạn, thì bạn nên sử dụng IDataErrorInfo vì nó đặt logic gần hơn với chủ sở hữu của chúng.

Nếu lớp doanh nghiệp của bạn là một lớp sơ khai được tạo bởi một tham chiếu đến dịch vụ WCF / XmlWeb thì bạn không thể / không được sử dụng IDataErrorInfo cũng như ném Exception để sử dụng với ExceptionValidationRule. Thay vào đó, bạn có thể:

  • Sử dụng Quy tắc xác thực tùy chỉnh.
  • Xác định một phần lớp trong dự án WPF UI của bạn và triển khai IDataErrorInfo.

1
Tôi biết điều này đã cũ, nhưng tôi hy vọng Alex sẽ có thể đáp ứng. Đây là kết luận tôi cũng đi đến, nhưng vấn đề là bạn phải viết một số xác thực cho (ví dụ) thuộc tính "Tuổi" không thể lớn hơn 100 trong ValidationRule, sau đó lặp lại logic tương tự trong giao diện IDataErrorInfo , sẽ lặp lại logic. Có đường nào quanh đó không?
JFTxJ

Bạn lặp lại logic ở đâu? trong một số loại xác thực máy chủ? Theo nhận xét của bạn, tôi đoán rằng bạn đang xác thực với IDataErrorInfo trong giao diện người dùng và sao chép xác thực trong đối tượng doanh nghiệp, phải không? Nếu đúng như vậy, thì việc xác thực ở cả hai bên là chính xác. Các đối tượng kinh doanh không thể tin tưởng giao diện người dùng và phải thực hiện xác thực riêng của nó (mặc dù nó có vẻ trùng lặp)
Alex Pollan

Không, sự trùng lặp của logic xác thực nằm trong IDataErrorInfo và trong Quy tắc xác thực tùy chỉnh ... Vì Quy tắc xác thực tùy chỉnh là cách duy nhất để xác thực dữ liệu TRƯỚC KHI nó thực sự được cập nhật vào đối tượng bị ràng buộc, xác thực đó (Tuổi phải thấp hơn thì 100) cần được xác định trong IDataErrorInfo để trả về thông báo "mỗi trường", nhưng cũng phải được triển khai trong Quy tắc xác thực tùy chỉnh. Có ý nghĩa?
JFTxJ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.