繁体   English   中英

从ViewModel回调到View

[英]Callback from ViewModel to 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()
}

我希望仅在VM.getData()完全执行后再执行BuildUI()方法,然后再通过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.
      }

BackgroundWorker完成工作后,您应该检索数据。 您的视图模型应实现INotifyPropertyChanged接口,并通过该视图绑定到的属性公开数据。 然后,视图模型可以在数据可用时(即BackgroundWorker已完成其工作)通知视图。

一种方法是使用消息传递。 也就是说,在视图上注册您的消息,然后从视图模型向视图发送消息,当收到此消息时,您可以调用BuildUI方法。

例如,如果您使用的是MvvmLight框架,则这是一种传递错误消息以显示在对话框中的方法。 您可能不想显示一个对话框(我手头有此代码),但是过程是相同的,只是注册和发送的消息类型不同。

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.
        });
     }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM