2009-06-17 34 views
17

Giả sử tôi có Chế độ xem được gắn với Chế độ xemMô hình A có bộ sưu tập quan sát Khách hàng.WPF Converters có thể được sử dụng như thế nào trong một mẫu MVVM?

Lợi thế của mẫu MVVM này là tôi cũng có thể liên kết Chế độ xem với Chế độ xemModel B làm đầy dữ liệu với các dữ liệu khác nhau.

Nhưng điều gì xảy ra nếu trong số Xem trình chuyển đổi chuyển đổi để hiển thị khách hàng của tôi, ví dụ: Tôi có một "ContractToCustomerConverter" chấp nhận một Hợp đồng và trả về Khách hàng thích hợp được hiển thị.

Vấn đề với điều này là bộ chuyển đổi tồn tại bên ngoài mẫu MVVM và do đó không biết rằng ViewModel của tôi có nguồn khác cho khách hàng.

  • là có một cách để Xem để vượt qua các ViewModel vào Chuyển đổi để nó tham gia vào tách mà mô hình MVVM cung cấp?
  • có cách nào cho tôi bằng cách nào đó bao gồm Trình chuyển đổi trong ViewModel của mình để trình chuyển đổi sử dụng các phụ thuộc hiện tại mà ViewModel có sẵn không?
  • hoặc là bộ chuyển đổi chỉ mã được tôn vinh và do đó không được sử dụng trong mẫu MVVM, vì vậy nếu bạn đang sử dụng MVVM thì bạn chỉ cần tạo "bộ chuyển đổi" của riêng mình (phương thức trên lớp ViewModel). , Đối tượng hiển thị, FlowDocuments, v.v ... để được sử dụng trên chế độ xem, thay vì sử dụng trình chuyển đổi ở tất cả?

(tôi đi theo những câu hỏi sau khi nhìn thấy việc sử dụng các chuyển đổi trong ứng dụng bản demo WPF mà đi kèm với các MVVM Template Toolkit download, xem "Messenger mẫu" sau khi giải nén nó.)

Trả lời

8

chuyển đổi nên hiếm khi được được sử dụng với MVVM. Trong thực tế, tôi cố gắng không sử dụng chúng cả. VM nên làm mọi thứ mà khung nhìn cần để hoàn thành công việc của mình. Nếu chế độ xem cần số Customer dựa trên số Contract, thì phải có thuộc tính Customer trên máy ảo được cập nhật bởi lôgic VM bất cứ khi nào thay đổi Contract.

Lợi thế của mẫu MVVM này là tôi cũng có thể liên kết Chế độ xem với ViewModel B điền vào dữ liệu khác nhau.

Tôi tranh chấp xác nhận quyền sở hữu đó. Theo kinh nghiệm của tôi, lượt xem không được chia sẻ giữa các loại máy ảo khác nhau và cũng không phải là mục tiêu của MVVM.

+3

OK Tôi thấy quan điểm của bạn về lượt xem không nên được chia sẻ trên các máy ảo khác nhau, nhưng ViewModel sẽ có thể được chia sẻ bởi các Chế độ xem khác nhau, do đó lợi thế của khả năng thử nghiệm của MVVM, phải không? Bạn sẽ có thể kết nối chế độ xem mô hình và mô hình giả lập với ViewModel để đảm bảo rằng tất cả các kết hợp dữ liệu mà nó nhận được từ mô hình giả tạo sẽ tạo ra các giá trị thuộc tính chính xác được hiển thị cho khung nhìn. Bạn có đồng ý không? –

12

Tôi thường không sử dụng bộ chuyển đổi nào cả trong MVVM, ngoại trừ các tác vụ UI thuần túy (ví dụ như BooleanToVisibilityConverter). IMHO bạn chứ không nên tuyên bố một tài sản khách hàng của loại CustomerViewModel trong ContractViewModel của bạn, chứ không phải sử dụng một ContractToCustomerConverter

11

Trong this conversation có một bình luận rằng đồng ý với vị trí Kent, không sử dụng chuyển đổi ở tất cả, thú vị:

ViewModel cơ bản là một công cụ chuyển đổi giá trị trên steroid.Dữ liệu "thô" và chuyển đổi dữ liệu thành nội dung thân thiện với thuyết trình và ngược lại. Nếu bạn đã từng thấy mình gắn kết thuộc tính của một phần tử với thuộc tính của ViewModel và bạn đang sử dụng trình chuyển đổi giá trị, hãy dừng lại! Tại sao không chỉ tạo thuộc tính trên ViewModel cho thấy dữ liệu "được định dạng" và sau đó thả công cụ chuyển đổi giá trị hoàn toàn?

Và trong this conversation:

Nơi duy nhất tôi có thể nhìn thấy một sử dụng cho chuyển đổi giá trị trong một MVVM kiến ​​trúc là cross-yếu tố bindings. Nếu tôi ràng buộc Khả năng hiển thị của bảng điều khiển với IsChecked của một Hộp kiểm, thì tôi sẽ cần sử dụng BooleanToVisibilityConverter.

5

Đối với những người không nói "không chuyển đổi không tầm thường" trong chế độ xem, bạn xử lý như thế nào?

Giả sử tôi có Mô hình cảm biến khí hậu đại diện cho chuỗi thời gian đọc từ các công cụ khác nhau (phong vũ biểu, máy đo độ ẩm, nhiệt kế, v.v.) tại một vị trí nhất định.

Giả sử Mô hình xem của tôi hiển thị bộ sưu tập cảm biến quan sát được từ Mô hình của tôi.

Tôi có Chế độ xem có chứa Bộ công cụ WPF DataGrid liên kết với Chế độ xem với thuộc tính ItemsSource được đặt thành bộ sưu tập cảm biến quan sát được. Làm cách nào để thể hiện chế độ xem của từng công cụ cho một cảm biến nhất định? Bằng cách hiển thị biểu đồ nhỏ (nghĩ Edward Tufte sparkline tại đây) được tạo bằng cách chuyển đổi chuỗi thời gian thành nguồn hình ảnh bằng cách sử dụng công cụ chuyển đổi (TimeSeriesToSparklineConverter)

Đây là cách tôi nghĩ về MVVM: Mô hình hiển thị dữ liệu cho mô hình Xem. Mô hình Xem hiển thị hành vi, Dữ liệu mô hình và trạng thái cho Chế độ xem. Số lượt xem thực hiện công việc đại diện cho dữ liệu Mô hình trực quan và cung cấp giao diện cho các hành vi nhất quán với trạng thái Chế độ xem.

Do đó, tôi không tin rằng hình ảnh lấp lánh trong Mô hình (Mô hình là dữ liệu, không phải là đại diện trực quan cụ thể của nó). Tôi cũng không tin rằng hình ảnh lấp lánh trong Mô hình Xem (điều gì sẽ xảy ra nếu Chế độ xem của tôi muốn đại diện cho dữ liệu khác nhau, chẳng hạn như hàng lưới chỉ hiển thị tối thiểu, tối đa, trung bình, độ lệch chuẩn vv của chuỗi?). Vì vậy, có vẻ như với tôi rằng View nên xử lý công việc chuyển đổi dữ liệu vào biểu diễn mong muốn. Vì vậy, nếu tôi muốn để lộ các hành vi, dữ liệu mô hình và trạng thái cho một mô hình xem nhất định trong một giao diện dòng lệnh thay vì một giao diện WPF, tôi không muốn mô hình của tôi cũng không xem mô hình của tôi có chứa hình ảnh. Điều này có sai không? Chúng ta có một số SensorCollectionGUIViewModelSensorCollectionCommandLineViewModel không? Điều đó có vẻ sai với tôi: Tôi nghĩ về Mô hình Xem như một biểu diễn trừu tượng của chế độ xem, chứ không phải cụ thể và gắn với một kỹ thuật cụ thể như những tên này cho thấy chúng.

Đó là nơi tôi hiểu rõ về MVVM. Vì vậy, đối với những người nói không sử dụng bộ chuyển đổi, bạn đang làm gì ở đây?

+3

Tôi thấy vấn đề bạn mô tả như thế này: Với một công cụ chuyển đổi giá trị, bạn sẽ tạo một ClimateSensorToSparklineGraphConverter, một bộ sưu tập các cảm biến khí hậu và đưa ra một hình ảnh. Đối với một cái gì đó giống như tạo ra một hình ảnh bitmap, bạn sẽ không được làm điều này với một DataTemplate và một bộ sưu tập của ViewModels có chứa ViewModels, tại một số điểm bạn cần mã C# để tạo ra hình ảnh. Sự cố xảy ra khi trong trình chuyển đổi bạn cũng truy cập, ví dụ: bộ sưu tập Người dùng để xác định những gì người dùng hiện tại được phép xem. Điều này sẽ phá vỡ MVVM vì ViewModel nên có người dùng được tiêm. –

0

Tôi sẽ thêm 2 xu vào cuộc thảo luận này.

Tôi sử dụng trình chuyển đổi, ở đây có ý nghĩa.

Giải thích: Có những trường hợp bạn cần đại diện cho 1 giá trị trong Mô hình theo nhiều cách hơn trong giao diện người dùng. Tôi phơi bày giá trị này thông qua 1 loại. Loại khác là loại được xử lý thông qua bộ chuyển đổi. Nếu bạn để lộ 1 giá trị thông qua 2 thuộc tính trong VM, bạn sẽ cần phải xử lý các thông báo cập nhật theo cách thủ công.

Ví dụ: tôi có mô hình có 2 int: TotalCount, DoneCount. Bây giờ tôi muốn cả hai giá trị này được hiển thị trong TextBlocks và ngoài ra tôi muốn hiển thị phần trăm thực hiện.

Tôi giải quyết vấn đề này bằng cách sử dụng DivisionConverter nhiều bộ chuyển đổi có 2 int được đề cập trước đó.

Nếu tôi có đặc biệt PercentDone trong VM, tôi cần phải cập nhật thuộc tính này bất cứ khi nào DoneCount được cập nhật.

+0

Về cơ bản bạn cập nhật thuộc tính PercentDone bằng cách khai báo trình biến đổi và kích hoạt nó khi liên kết của bạn ném một propertychanged, chỉ nó được đại diện bởi một lớp với một hàm, chứ không phải là một thuộc tính ... Vì vậy, tôi không nghĩ đây là một thực tế trường hợp sử dụng tốt. Tôi nghĩ giao diện người dùng UI-to-UI tinh khiết đảm bảo cho người chuyển đổi. – Joris

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