从ViewModel回调到视图
问题描述:
我的视图调用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.
}
答
你应该检索数据一旦BackgroundWorker
已完成其工作。您的视图模型应该实现INotifyPropertyChanged接口并通过视图绑定的属性公开数据。当数据可用时,视图模型可以通知视图(即BackgroundWorker
已完成其工作)。
答
一种方法是使用消息传递。也就是说,在视图中注册消息,然后从视图模型向视图发送消息,当收到此消息时,您可以调用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.
});
}
你需要明确具体的关于你的要求,否则你不会得到有用的答案。请更新您的问题。 – Bernard 2012-08-10 02:20:00
对不起,我更新了我的oroginal Post,请让我知道如果它不明确。 – nmgans 2012-08-10 02:29:36