2011-03-22 75 views
1

我有一個循環訪問IEnumerable集合的方法,並將它們傳遞給另一個方法。例如:如何使用IEnumerable實現進度?

void Run (object item) 
{ 
    foreach(var method in this.Methods) 
     method (item); 
) 

我該如何實現進度條中反映的進度排序?我可以很容易地做到這一點,如果它是直接編碼在這種方法,但這種方法是包含在ViewModel以外的類型,我當然可以調用。

我只是不知道如何實現它,並從該方法得到它,反映UI的變化,將它傳遞給ViewModel

任何想法?

+0

不要讓這個遞歸於你。如果'Run'在'this.Methods'裏面,你就會有一個裝滿蜂蠟的盤子! – corsiKa 2011-03-22 21:44:28

+0

哈哈,你是什麼意思? this.Methods包含來自許多不同靜態類的方法,但不包含它自己。 – 2011-03-22 21:45:20

回答

2

我會通過使用以下事件來解決這個問題。

public class ViewModel : ViewModelBase 
{ 
    private int m_CurrentProgress; 
    private int m_MethodCount; 

    // Bind this to the progress bar 
    public int CurrentProgress 
    { 
     get { return m_CurrentProgress; } 
     set 
     { 
      m_CurrentProgress = value; 
      OnPropertyChanged("CurrentProgress"); 
     } 
    } 

    // Bind this to the progress bar 
    public int MethodCount 
    { 
     get { return m_MethodCount; } 
     set 
     { 
      m_MethodCount = value; 
      OnPropertyChanged("MethodCount"); 
     } 
    } 

    private void MethodExecuted(object sender, EventArgs e) 
    { 
     CurrentProgress++; 
    } 

    public void Run() 
    { 
     var c = new ExternalClass(); 
     MethodCount = c.Methods.Count; 
     c.MethodExecuted += MethodExecuted; 

     c.Run(null); 
    } 
} 

public class ExternalClass 
{ 
    public List<object> Methods { get; set; } 

    public event EventHandler<EventArgs> MethodExecuted; 

    public void InvokeMethodExecuted(EventArgs e) 
    { 
     EventHandler<EventArgs> handler = MethodExecuted; 
     if (handler != null) 
     { 
      handler(this, e); 
     } 
    } 

    public void Run(object item) 
    { 
     foreach (var method in Methods) 
     { 
      method(item); 

      InvokeMethodExecuted(null); 
     } 
    } 
} 
+0

謝謝btw ExternalClass是靜態的。這很重要嗎?我可以轉換它,但不知道這個想法是否仍然有效。 – 2011-03-22 21:55:07

+0

理想情況下,類將被實例化,這樣你就不會有一個靜態事件,如果你在不同的線程上多次運行這些東西,那麼這個靜態事件可能會變得混亂,如果不是這種情況,那麼你可以使它變成靜態的。不應該是一個問題。 – bic 2011-03-22 21:57:17

2

我最終做的是傳遞用於報告進度的委託。這提供了非常好的解耦。該委託可以實現爲一個lambda函數,它可以直接設置表單上的進度。

void Run (object item, Action<float> progress) 
{ 
    int total = MethodCollection.Count; 
    int index = 0; 
    foreach(var method in MethodCollection) 
    { 
     method (item); 
     progress(index/(float)total); 
    } 
) 

對於長時間運行的任務,我會做這個使用BackgroundWorker的,它具有內置掛鉤報告進度一個單獨的線程。

+0

你能告訴我這將如何使用?我正在嘗試查看如何在調用者中指定Action,僅供想法。 – 2011-03-22 21:47:15