2012-08-10 75 views
1

我的視圖調用ViewModel中的方法來獲取數據。獲取數據後,我根據從ViewModel返回的數據構建View(Grid)。從ViewModel回調到視圖

getData()View Model中的方法在BackgroundWorker線程中運行。現在我的問題是如何在View完成獲取所有數據後返回View?

ViewModel 
    { 
     getData() 
     { 
      WorkerMethods() 
      WorkerCompletedMethod() 
      { 
       Refresh() 
      } 
     } 


     Refresh() 
     { 
      WorkerMethod() 
      WorkerCompleted() 
      { 
       data - Retrieved. 
       This is where all the calls are really DONE 
      } 
     } 

    } 

從查看,我會打電話

View() 
{ 
    VM.getData() 
    //Before I call this method, I want to make sure Refresh() is completed 
    BuildUI() 
} 

我只想要VM.getData(後要執行的BuildUI()方法)完全執行,又與刷新完成()方法,這也是我需要能夠動態構建UI的數據。


這就是我要做的。請糾正我,如果這是不正確的做法。

在後面的視圖代碼,

View 
    { 

     public delegate void DelegateRefresh(); 
     Init() 
     { 
      DelegateRefresh fetcher = RefreshData; 
      fetcher.BeginInvoke(null, null); 
     } 


     public void RefreshData() 
     { 
     _viewModel.GetData(); 
     **while (_viewModel.IsBusy)** 
     {    
      continue; 
     } 
     BuildUI(); 
     } 

     BuildUI() 
     { 
     //Code to build the UI Dynamically using the data from VM. 
     } 

回答

1

你應該檢索數據一旦BackgroundWorker已完成其工作。您的視圖模型應該實現INotifyPropertyChanged接口並通過視圖綁定的屬性公開數據。當數據可用時,視圖模型可以通知視圖(即BackgroundWorker已完成其工作)。

+0

你需要明確具體的關於你的要求,否則你不會得到有用的答案。請更新您的問題。 – Bernard 2012-08-10 02:20:00

+0

對不起,我更新了我的oroginal Post,請讓我知道如果它不明確。 – nmgans 2012-08-10 02:29:36

0

一種方法是使用消息傳遞。也就是說,在視圖中註冊消息,然後從視圖模型向視圖發送消息,當收到此消息時,您可以調用BuildUI方法。

例如,如果您使用的是MvvmLight框架,以下是一種傳回錯誤消息以顯示在對話框中的方法。您可能不想顯示對話框(手頭上有此代碼),但過程相同,只是用於註冊和發送的不同消息類型。

視圖模型:

public class ErrorMessage : DialogMessage 
{ 
    // See MvvmLight docs for more details, I've omitted constructor(s) 

    /// <summary> 
    /// Registers the specified recipient. 
    /// </summary> 
    /// <param name="recipient">The recipient of the message.</param> 
    /// <param name="action">The action to perform when a message is sent.</param> 
    public static void Register(object recipient, Action<ErrorMessage> action) 
    { 
     Messenger.Default.Register<ErrorMessage>(recipient, action); 
    } 

    /// <summary> 
    /// Sends error dialog message to all registered recipients. 
    /// </summary> 
    public void Send() 
    { 
     Messenger.Default.Send<ErrorMessage>(this); 
    } 
} 

public class SomeViewModel : ViewModelBase 
{ 
    public void SendErrorMessage(string message) 
    { 
     var errorMessage = new ErrorMessage(message); 
     errorMessage.Send(); 
     // Or in your case, when the background worker is completed.   
    } 
} 

查看:

public partial class SomeView : Window 
{ 
    public SomeView() 
    { 
     InitializeComponent(); 
     ErrorMessage.Register(this, msg => 
     { 
      MessageBoxResult result = MessageBox.Show(msg.Content, msg.Caption, 
       msg.Button, msg.Icon, msg.DefaultResult, msg.Options); 
      msg.ProcessCallback(result); 
      // Or in your case, invoke BuildUI() method. 
     }); 
    } 
+0

感謝您的建議。儘管我沒有使用MvvmLight框架。我們正在使用PRISM。無論如何,這是我最終做的。我創建了一個委託方法,並在其上調用了BeginInvoke()。在委託方法內部,我將檢查ViewModel中的IsBusy屬性是否爲true,一旦它爲false,我知道我已完成View Model中的工作。將在原始帖子中發佈代碼。 – nmgans 2012-08-10 14:05:45

+0

這將工作正常。我使用'IsWaiting'和轉換器爲鼠標光標做類似的操作。 – si618 2012-08-13 01:51:58