[英]WPF Caliburn.Micro - Best way to navigate in Singe Window Application
我正在開發一個WPF應用程序,它將在觸摸屏上全屏運行。 我的應用程序中的導航只能通過單擊每個頁面上的按鈕(“后退”或“注銷”)來完成。
這不是通用應用程序,但它看起來像。
項目假設:
問題和疑問:
我有一個窗口和3個UserControl(和ViewModels) 概念藝術
Window ShellView
UserControl LoginView
UserControl OrdersView
UserControl OrderDetailView
當應用程序啟動時,我將LoginView設置為默認值並使用CM Conductor ActivateItem方法加載它,但我不知道如何從UserControl設置另一個View,如LoginView
我讀過: 這個問題,但這不包括我的案例和答案,但這對我來說很難理解。
我的想法:
ShellViewModel
public static void setOrdersView() {
ActivateItem(new OrdersViewModel());
// Error : An object reference is required for the non-static field, method, or property 'Caliburn.Micro.ConductorBase<object>.ActivateItem(object)
}
ShellViewModel.setOrdersView();
問題:在這種情況下,處理導航的最佳方法是什么?
ShellView
<Window>
<ContentControl x:Name="ActiveItem" />
</Window>
ShellViewModel
public class ShellViewModel : Conductor<object>, IShell
{
public ShellViewModel()
{
LoadDefault();
}
public void LoadDefault()
{
ActivateItem(new LoginViewModel());
}
}
LoginView
<UserControl>
<Button x:Name="Login" />
</UserControl>
LoginViewModel
public class LoginViewModel : PropertyChangedBase
{
public void Login() {
if (LoginManager.Login("User", "Password")) {
// How to redirect user to OrdersView?
}
}
}
我有類似的應用程序,一個shell窗口和許多激活的視圖內部和一些對話框窗口。 您應該使用EventAggregator模式滿足這些需求,Caliburn已經實現了。
如何實現 :
最小Shell
簽名
public class ShellViewModel : Conductor<object>,
IHandle<ChangePageMessage>,
IHandle<OpenWindowMessage>
你需要兩個字段(第二個用於對話框):
public IEventAggregator EventAggregator { get; private set; }
public IWindowManager WindowManager { get; private set; }
我通過IoC設置了這些對象的單個實例。 您也可以將它們定義為單身人士。 EventAggregator需要在實現IHandle
的對象上進行訂閱。
EventAggregator.Subscribe(this); //You should Unsubscribe when message handling is no longer needed
處理程序實現:
public void Handle(ChangePageMessage message) {
var instance = IoC.GetInstance(message.ViewModelType, null);//Or just create viewModel by type
ActivateItem(instance);
}
public void Handle(OpenWindowMessage message) {
var instance = IoC.GetInstance(message.ViewModelType, null);//Or just create viewModel by type
WindowManager.ShowWindow(instance);
}
事件聚合器的消息只能是標記類,但有時傳遞更多參數(如我們的OpenWindowMessage
和ChangePageMessage
類)很有用 - 它們與內容完全相似,例如:
public class OpenWindowMessage {
public readonly Type ViewModelType;
public OpenWindowMessage(Type viewModelType) {
ViewModelType = viewModelType;
}
}
您的所有viewModel也可以訂閱EventAggregator實例並處理一些消息以進行通信,甚至是初始參數。 我幾乎為每個viewModel都有類似MyViewModelInitMessage
類的東西,並且只使用兩個發布方法。
EventAggregator.Publish(new ChangePageMessage(typeof(MyViewModel)));
EventAggregator.Publish(new MyViewModelInitMessage("...all needed parameters"));
因此,當我發布這兩個 - 我的ViewModel
將被激活,然后它訂閱EventAggregator
( 不要忘記這樣做或第二個消息處理永遠不會發生 ),並將在之后處理它的InitMessage
。
現在使用EventAggregator,您可以在當前訂閱它的所有ViewModel之間發送消息。
這似乎很常見的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.