1

My View は ViewModel のメソッドを呼び出してデータをフェッチします。データをフェッチした後、ViewModel から返されたデータに基づいて View(Grid) を構築します。

ビュー モデルの getData() メソッドは、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()
}

BuildUI() メソッドは、VM.getData() が完全に実行された後にのみ実行され、Refresh() メソッドでも実行されます。これには、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.
      }
4

2 に答える 2

1

BackgroundWorker作業が完了したら、データを取得する必要があります。ビューモデルはINotifyPropertyChangedインターフェイスを実装し、ビューがバインドするプロパティを介してデータを公開する必要があります。ビューモデルは、データが利用可能になったとき(つまり、BackgroundWorker作業が完了したとき)にビューに通知できます。

于 2012-08-10T02:12:07.563 に答える
0

1つのアプローチは、メッセージングを使用することです。つまり、メッセージをビューに登録してから、ビューモデルからビューにメッセージを送信します。このメッセージを受信したら、BuildUIメソッドを呼び出すことができます。

たとえば、MvvmLightフレームワークを使用している場合、ダイアログに表示するエラーメッセージを返す1つの方法があります。ダイアログを表示したくない場合もありますが(このコードは手元にあります)、プロセスは同じで、登録して送信するメッセージの種類が異なります。

ViewModel:

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.
        });
     }
于 2012-08-10T04:48:18.423 に答える