2013-05-02 35 views
10

Đây là một câu hỏi về kiến ​​trúc/thiết kế.Làm thế nào để tránh địa ngục dữ liệu/sự kiện trên màn hình phức tạp?

Tôi đã chạy vào một vài dự án trong quá khứ được viết bằng WPF/Windows Forms, v.v. có màn hình phức tạp với nhiều trường và các trường này được kết nối với nhau (giá trị của chúng phụ thuộc vào nhau với một số logic có tính liên quan). Các dự án này tôi đã thực hiện sau khi chúng được triển khai và tôi tìm thấy rất nhiều sự kiện/dữ liệu ràng buộc địa ngục - ý tôi là bởi vì tất cả các trường này phụ thuộc vào những trường khác mà chúng đã triển khai INotifyPropertyChanged và các trường khác đang được sửa đổi. Điều này gây ra các lĩnh vực tương tự được cập nhật 5-6 lần khi màn hình tải và thứ tự trong đó các lĩnh vực được dân cư gây ra lỗi khủng khiếp. (Ví dụ, ngày đã được thiết lập trước khi Loại công việc, thay vì sau Loại công việc, vì vậy tôi kết thúc với một khác nhau Job Phí.)

Để làm cho vấn đề tồi tệ hơn, một số hacks được thực hiện trên Sự kiện giao diện người dùng (ví dụ: DropDown đã thay đổi để cập nhật trường X) trong khi các sự kiện khác nằm trong mô hình miền mà giao diện người dùng liên kết.

Về cơ bản, đó là một mớ hỗn độn lớn, và tôi chỉ muốn biết cách tốt nhất để thực hiện điều gì đó như thế này là nếu tôi bắt đầu từ đầu. Hay bạn nên tránh một màn hình phức tạp như vậy ngay từ đầu?

Trả lời

0

Chúng tôi có giao diện người dùng khá phức tạp (bao gồm một số trường có liên quan thuộc nhiều loại khác nhau, ví dụ: Hàng trong DataGrid) và mẫu MVVM đã hoạt động khá tốt đối với chúng tôi. Tất cả các thuộc tính xuất phát từ mô hình và tiếp xúc với các Xem mà có logic phức tạp có liên quan được "bọc" bằng một tài sản tương đương trong ViewModel, mà không có Sao Field, nhưng thay vì chỉ trực tiếp đến Model:

public class SomeComplexViewModel 
{ 

    public SomeModel Model {get;set;} 

    public string SomeCrazyProperty 
    { 
     get 
     { 
      return Model.SomeCrazyProperty; 
     } 
     { 
      Model.SomeCrazyProperty = value; 
      //... Some crazy logic here, potentially modifying some other properties as well. 
     } 
    } 
} 

<TextBox Text="{Binding SomeCrazyProperty}"/> 

Điều này loại bỏ vấn đề "giá trị ban đầu", vì giá trị ban đầu được đọc bởi Ràng buộc thực sự là giá trị thực đến từ Mô hình, và do đó logic được đặt trong Setter chỉ được thực thi khi cần.

Sau đó, đối với tài sản giả (mà không có logic đằng sau), chúng tôi liên kết trực tiếp từ Xem để Model:

<TextBox Text="{Binding Model.SomeRegularProperty}"/> 

Điều này làm giảm sưng lên trong ViewModel.

Đối với các sự kiện trong mã phía sau, tôi hoàn toàn tránh điều đó. Mã của tôi đằng sau các tệp hầu như luôn là một InitializeComponent() và không có gì khác.

Chỉ logic cụ thể xem được đặt trong mã phía sau (chẳng hạn như hình động, vv), khi không thể thực hiện trực tiếp trong XAML hoặc dễ thực hiện trong mã (không phải là trường hợp hầu hết thời gian).

Edit:

Điều quan trọng là bạn phải đề cập đến rằng winforms ràng buộc khả năng là một trò đùa so với những XAML-based. đó có thể là nguyên nhân khiến bạn thấy những mớ hỗn độn kinh khủng trong những dự án đó không?

2

Tôi sẽ cố gắng duy trì logic kinh doanh trong số những người định cư bất động sản càng nhiều càng tốt.

Trước hết, nếu cần một số thuộc tính cho một phép tính, tôi sẽ viết một phương pháp tính toán và gọi phương thức đó khi thích hợp. Ví dụ. nếu tất cả các kết hợp khác nhau của giá trị thuộc tính có ý nghĩa, người ta chỉ có thể gọi phương thức trong bộ giải mã của từng thuộc tính, đảm bảo rằng cùng một mã sẽ chạy bất kỳ lúc nào một trong các thuộc tính được thay đổi. Nếu bạn chỉ có thể đánh giá các kết hợp đặc biệt của giá trị thuộc tính, bạn có thể triển khai lệnh và cho phép người dùng quyết định khi nào tính toán các thay đổi kết quả hoặc bạn có thể cung cấp phản hồi thông qua xác thực và chỉ đánh giá thay đổi thuộc tính nếu kết hợp hợp lệ. Nếu có một số thuộc tính phụ thuộc lẫn nhau, tôi thường sử dụng biến "ChangeInitiator" để chỉ ra thuộc tính nào đã thay đổi, do đó rõ ràng trong phương pháp tính toán thuộc tính chịu trách nhiệm cho thay đổi và những thay đổi nào khác sẽ thay đổi. Về cơ bản, điều này giống như thực hiện một phần của phép tính trong mỗi thuộc tính setter, nhưng tôi thấy rằng nó giúp tôi giữ tổng quan về mọi thứ nếu các phần khác nhau của mối quan hệ là tất cả trong một phương thức. Trong một chương trình tôi đã viết một lần, tôi đã có một số tính toán chạy theo một chuỗi nền định kỳ, vì vậy tôi sẽ chỉ đặt cờ bất cứ khi nào một phần dữ liệu thay đổi yêu cầu tính toán mới và thực hiện tất cả các cập nhật dựa trên bộ hẹn giờ cứ hai giây một lần ... điều đó cũng có thể giúp bạn có được logic thẳng hơn, và tránh né việc tính toán chạy nhiều lần cho một tập hợp các thay đổi có liên quan.

Đối với thông báo thay đổi, tôi thực sự cố gắng chỉ sử dụng nó cho ràng buộc dữ liệu UI.

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