2010-08-19 35 views
31

Tôi có ứng dụng WPF được xây dựng trên mẫu thiết kế MVVM.Cách triển khai thanh tiến trình bằng mẫu MVVM

Tôi muốn triển khai thanh tiến trình trong ứng dụng, tuân theo mẫu MVVM.

Có ai có bất kỳ đề xuất nào về cách triển khai tính năng này không?

Cảm ơn trước

Trả lời

52

Điển hình là giao diện người dùng của bạn sẽ chỉ đơn giản là liên kết với các thuộc tính trong VM của bạn:

<ProgressBar Value="{Binding CurrentProgress, Mode=OneWay}" 
      Visibility="{Binding ProgressVisibility}"/> 

VM của bạn sẽ sử dụng một BackgroundWorker để làm việc trên một sợi nền, và để cập nhật định kỳ các Giá trị CurrentProgress. Một cái gì đó như thế này:

public class MyViewModel : ViewModel 
{ 
    private readonly BackgroundWorker worker; 
    private readonly ICommand instigateWorkCommand; 
    private int currentProgress; 

    public MyViewModel() 
    { 
     this.instigateWorkCommand = 
       new DelegateCommand(o => this.worker.RunWorkerAsync(), 
            o => !this.worker.IsBusy); 

     this.worker = new BackgroundWorker(); 
     this.worker.DoWork += this.DoWork; 
     this.worker.ProgressChanged += this.ProgressChanged; 
    } 

    // your UI binds to this command in order to kick off the work 
    public ICommand InstigateWorkCommand 
    { 
     get { return this.instigateWorkCommand; } 
    } 

    public int CurrentProgress 
    { 
     get { return this.currentProgress; } 
     private set 
     { 
      if (this.currentProgress != value) 
      { 
       this.currentProgress = value; 
       this.OnPropertyChanged(() => this.CurrentProgress); 
      } 
     } 
    } 

    private void DoWork(object sender, DoWorkEventArgs e) 
    { 
     // do time-consuming work here, calling ReportProgress as and when you can 
    } 

    private void ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     this.CurrentProgress = e.ProgressPercentage; 
    } 
} 
+0

Xin chào Kent, tôi có cần mô hình riêng biệt và mô hình xem cho thanh tiến trình không? hoặc tôi sẽ thêm một thanh tiến trình cho mỗi chế độ xem hiện tại mà tôi định sử dụng nó? – jpgooner

+0

Tôi sẽ bắt đầu đơn giản bằng cách sử dụng một lượt xem và sau đó quyết định xem bạn có thể trừu tượng hóa thành thành phần có thể sử dụng lại hay không. –

+0

Yep hét to, cảm ơn câu trả lời của bạn everone – jpgooner

8

Sử dụng một điều khiển ProgressBar và ràng buộc tài sản Value của mình cho một tài sản của ViewModel:

Xem

<ProgressBar Minimum="0" Maximum="0" Value="{Binding CurrentProgress}" /> 

ViewModel

private double _currentProgress; 
public double CurrentProgress 
{ 
    get { return _currentProgress; } 
    private set 
    { 
     _currentProgress = value; 
     OnPropertyChanged("CurrentProgress"); 
    } 
} 
+0

Làm cách nào để kết nối điều này với Lệnh của tôi? Tức là, tôi có một nút bấm và bấm vào, tôi muốn bắt đầu thanh tiến trình cho đến khi hành động được thực hiện. –

+0

@KalaJ, bạn chỉ cần cập nhật thuộc tính CurrentProgress trong hành động của bạn (ví dụ nếu đó là vòng lặp, hãy cập nhật giá trị ở mỗi lần lặp lại) –

+0

Điều tôi đang chờ hệ thống đọc/phát hiện đĩa CD khi tôi chèn CD vào máy tính của tôi. Đôi khi phải mất một thời gian để hệ thống đọc đĩa CD khác. Làm cách nào để cập nhật giá trị như vậy? Tôi đã suy nghĩ có thể sử dụng một thanh tiến trình không xác định nhưng tôi vẫn còn bối rối về cách kết nối nó với Command của tôi? –

6

Thêm hai thuộc tính để VM của bạn:

bool IsProgressBarVisible 
double ProgressValue 

Nếu bạn bắt đầu một hoạt động thời gian dài trong VM của bạn, đặt IsProgressBarVisible-tài sản cho đúng và thiết lập các kỳ ProgressValue với giá trị tiến bộ hiện nay. Hãy thử tính giá trị từ 0 đến 100. Điều này có lợi thế là bạn không phải cung cấp giá trị tối thiểu và tối đa. Sau khi hoàn thành thao tác không đồng bộ, đặt IsProgressBarVisible thành false.

Trong XAML, liên kết với hai thuộc tính này. Sử dụng công cụ chuyển đổi giá trị để chuyển đổi chế độ hiển thị boolean thành Visibility.

<ProgressBar Value="{Binding ProgressValue}" Visibility="{Binding IsProgressBarVisible,Converter={StaticResource BooleanToVisibility_ValueConverter}}"/> 
Các vấn đề liên quan