nuk*_*bit 5 c# windows-runtime mvvmcross winrt-xaml
我刚刚开始使用MvvmCross,但我没有找到任何关于如何从ViewModel执行UI代码的信息.
在Caliburn上有coroutine,所以我可以访问视图并保持ui代码与viewmodel代码分开.在我的第一个案例中,我需要从ViewModel中的命令打开一个拨号,这是正确的方法吗?
现在我正在开发一个WinRT应用程序.
谢谢
Stu*_*art 14
在MvvmCross中没有任何硬/快的规则.
通常,当我需要这样做时,我使用Messenger插件.
这个答案假设您使用的是最新的Alpha v3代码.对于较旧的vNext代码,您必须进行一些翻译 - 请参阅下面的注释.
要使用这种方法:
我参考Cirrious.MvvmCross.Plugins.Messenger.dll了Core和UI项目.
然后我在Setup.cs(例如in InitializeLastChance)中的某处添加一行到:
Cirrious.MvvmCross.Plugins.Messenger.PluginLoader.Instance.EnsureLoaded();
Run Code Online (Sandbox Code Playgroud)
然后在Core项目中我添加一条消息:
public class InputIsNeededMessage : MvxMessage
{
public InputIsNeededMessage(object sender) : base(sender) {}
}
Run Code Online (Sandbox Code Playgroud)
在ViewModel中,我可以通过构造函数注入或通过以下方式获取Messenger:
var messenger = Mvx.Resolve<IMvxMessenger>();
Run Code Online (Sandbox Code Playgroud)
我可以通过以下方式发送消息:
messenger.Publish(new InputIsNeededMessage(this));
Run Code Online (Sandbox Code Playgroud)
在视图中,我可以再次访问信使并使用以下命令订阅消息:
var messenger = Mvx.Resolve<IMvxMessenger>();
_token = messenger.SubscribeOnMainThread<InputIsNeededMessage>(OnInputIsNeeded);
Run Code Online (Sandbox Code Playgroud)
这里_token 必须是一个成员变量-如果它不是,则认购事项将不会继续存在-认购本身是弱默认(所以你从来没有退订)
在哪里OnInputIsNeeded是这样的:
private void OnInputIsNeeded(InputIsNeededMessage message)
{
if (message.Sender != ViewModel)
return;
// do stuff here - you are already on the UI thread
}
Run Code Online (Sandbox Code Playgroud)
以上序列是我通常为"正确代码"所做的
首先使用Messenger/EventAggregator可能会感到不舒服 - 它肯定花了我一段时间才习惯它 - 但是在我习惯了它之后,我现在到处使用它 - pub/sub Message decoupling非常灵活测试和未来的代码维护(IMO)
作为上述方法的替代方案,我有时会采取捷径:
很抱歉使用v3语法 - 但转换即将到来,这就是我现在编写的内容......
切换回vNext我想你可能需要:
IMessenger而不是IMvxMessengerBaseMessage而不是MvxMessageSubscribe而不是SubscribeOnMainThread- 但是你需要自己将消息编组到UI线程上.