2013-02-08 32 views
10

Tôi đang sử dụng mẫu MVVM trong ứng dụng WPF của chúng tôi để cho phép kiểm tra đơn vị toàn diện. Bản thân mẫu MVVM đang hoạt động rất tốt, tuy nhiên tôi đang cố gắng thích nghi với mô hình theo cách có nghĩa là tôi có thể sử dụng hỗ trợ dữ liệu thời gian thiết kế của WPF.Sử dụng dữ liệu thiết kế WPF với mẫu MVVM

Như tôi đang sử dụng Prism các trường hợp ViewModel thường tiêm vào constructor của xem, như vậy

public MyView(MyViewModel viewModel) 
{ 
    DataContext = viewModel; 
} 

Dependencies cho ViewModel này sau đó được tiêm vào các nhà xây dựng, như vậy

public class MyViewModel 
{ 
    public MyViewModel(IFoo foo, IBar bar) 
    { 
     // ... 
    } 

    // Gets and sets the model represented in the view 
    public MyModel { get; set; } 

    // Read-only properties that the view data binds to 
    public ICollectionView Rows { get; } 
    public string Title { get; } 

    // Read-write properties are databound to the UI and are used to control logic 
    public string Filter { get; set; } 
} 

Điều này thường hoạt động thực sự tốt trừ khi nói đến dữ liệu thiết kế - Tôi muốn tránh biên soạn các lớp dữ liệu thiết kế cụ thể vào assembly đã được phát hành của mình và vì vậy tôi đã chọn sử dụng phương pháp {d:DesignData} thay vìCách tiếp cận, tuy nhiên để điều này hoạt động chính xác, ViewModel của tôi bây giờ cần phải có một hàm tạo tham số. Ngoài ra, tôi cũng thường cần phải thay đổi các thuộc tính bổ sung để có các bộ định cư hoặc là các bộ sưu tập có thể sửa đổi để có thể thiết lập các thuộc tính này trong XAML.

public class MyViewModel 
{ 
    public MyViewModel() 
    { 
    } 

    public MyViewModel(IFoo foo, IBar bar) 
    { 
     // ... 
    } 

    // Gets and sets the model represented in the view 
    public MyModel { get; set; } 

    // My read-only properties are no longer read-only 
    public ObservableCollection<Something> Rows { get; } 
    public string Title { get; set; } 

    public string Filter { get; set; } 
} 

này là đáng lo ngại cho tôi:

  • Tôi có một constructor parameterless rằng không bao giờ được dự định sẽ được gọi và không phải là đơn vị được thử nghiệm
  • Có setters đối với tài sản mà chỉ có bản thân nên ViewModel được gọi
  • ViewModel của tôi giờ đây là một hỗn hợp lộn xộn của các thuộc tính cần được sửa đổi bởi chế độ xem và những thứ không nên - điều này khiến bạn khó hiểu được đoạn mã nào chịu trách nhiệm duy trì bất kỳ tài sản cụ thể nào
  • Đặt các thuộc tính nhất định tại thời điểm thiết kế (ví dụ: để xem kiểu dáng trên văn bản Filter) thực sự có thể kết thúc việc gọi logic ViewModel! (vì vậy ViewModel của tôi cũng cần phải được kích thích các phụ thuộc bắt buộc khác đang thiếu trong thời gian thiết kế)

Có cách nào tốt hơn để có được dữ liệu thời gian thiết kế trong một ứng dụng MVVM WPF theo cách không thỏa hiệp của tôi ViewModel theo cách này?

Ngoài ra, tôi có nên xây dựng ViewModel của mình theo cách khác để nó có các thuộc tính đơn giản hơn với logic tách ra ở một nơi khác.

Trả lời

-1

Tôi cũng đã làm việc với thử nghiệm NUnit với WPF và triển khai MVVM. Tuy nhiên, phiên bản của tôi bị đảo ngược từ máy của bạn. Bạn đang tạo khung nhìn đầu tiên, sau đó tạo mô hình để kiểm soát nó.

Trong phiên bản của mình, tôi tạo mô hình MVVM FIRST và đơn vị có thể kiểm tra nó cho đến khi bò về nhà và không lo lắng về bất kỳ thiết kế trực quan nào ... nếu mô hình bị hỏng.

trong mô hình MVVM của tôi, tôi có một phương thức để "GetTheViewWindow". Vì vậy, khi tôi bắt nguồn từ đường cơ sở MVVM của tôi, mỗi mô hình xem có quan điểm riêng của mình chịu trách nhiệm. Vì vậy, thông qua một phương pháp ảo, mỗi cá thể sẽ làm cửa sổ xem mới của riêng nó khi được áp dụng cho sản xuất.

public class MyMVVMBase 
{ 
    private MyViewBaseline currentView; 

    public MyMVVMBase() 
    { // no parameters required } 

    public virtual void GetTheViewWindow() 
    { throw new exception("You need to define the window to get";) } 
} 

public class MyXYZInstanceModel : MyMVVMBase 
{ 
    public override void GetTheViewWindow() 
    { 
     currentView = new YourActualViewWindow(); 
    } 
} 

Hy vọng điều này sẽ giúp thay thế cho những gì bạn đang gặp phải.

+2

Hơi lạ với tôi khi máy ảo của bạn có sự phụ thuộc vào lượt xem của bạn. –

+0

@GregD, không phải với tôi. Tôi sẽ có thể có mô hình này mà tôi có thể truy vấn dữ liệu, thiết lập cờ trên những gì có thể được trình bày cho bất kỳ "xem" bên ngoài thông qua lộ getters/setters. Tôi chỉ nói rằng trong ví dụ này, nó không YÊU CẦU chế độ xem, nhưng nếu tôi muốn khởi chạy chế độ xem, mỗi mô hình xem có mục đích riêng, chẳng hạn như màn hình bảo trì, xử lý chi tiết giao dịch/tiêu đề, bất cứ điều gì. Nếu có một cái nhìn tương ứng, tôi chỉ có móc để nói ... đi gọi chế độ xem được kết hợp với trình xử lý mvvm này. – DRapp

+0

Vậy dữ liệu thiết kế thời gian làm việc với phương pháp này như thế nào? – Justin

1

Trước tiên, tôi khuyên bạn nên xem this video nơi Brian Lagunas cung cấp một số phương pháp hay nhất về MVVM. Brian - ít nhất - tham gia vào sự phát triển của Prism, như tên của ông xuất hiện trong các thông tin gói nuget. Không kiểm tra thêm. Về phía tôi, tôi chỉ sử dụng bit Prism, và Model của tôi và ViewModel luôn cung cấp các hàm tạo trống (như những gì Brian cho thấy), bối cảnh dữ liệu được gán trong XAML của khung nhìn và tôi thiết lập các giá trị thuộc tính như:

<MyView.DataContext> 
    <MyViewModel /> 
</MyView.DataContext> 

public void BringSomethingNew() 
{  
    var myView = new View(); 
    (myView.DataContext as ViewModel).Model = myModel; 

    UseMyView(); 
} 

Một lợi ích khác với phương pháp này là ViewModel được tạo ra một lần, với cùng một con đường ở thiết kế và chạy thời gian, vì vậy bạn tạo các đối tượng ít hơn và tiết kiệm nỗ lực GC. Tôi thấy điều này thanh lịch.

Liên quan đến setters, dữ liệu thiết kế vẫn sẽ làm việc nếu bạn làm cho họ tin, như:

public string MyProp { get; private set; } 

Ok, tùy chỉnh nó để quản lý NotifyPropertyChange tại thuận tiện cho bạn, nhưng bạn đã có ý tưởng.

Hiện tại, tôi chưa có giải pháp để quản lý ObesrvableCollection s (tôi gặp vấn đề tương tự, mặc dù đặt nhiều giá trị trong XAML đôi khi hoạt động ... ???) và có, tôi đồng ý rằng bạn phải quản lý trường hợp khi các thuộc tính không được thiết lập, như thiết lập các giá trị mặc định trong hàm tạo.

Tôi hy vọng điều này sẽ hữu ích.

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