[英]Advice on Views navigation using Caliburn.Micro MVVM WPF
我是Caliburn Micro的新手,希望獲得一些建議,以采取哪些方式來開發我的應用程序界面和視圖之間的導航。 我的想法是要有一個MainWindow,它將包含一個按鈕菜單,每個按鈕都與一個特定的視圖相關。 每個視圖將存儲在單獨的WPF UserControl中。 mainWindow還將包含一個TabControl,該TabControl綁定到viewmodel上選項卡的ObservableCollection。 每次單擊菜單上的按鈕時,我想添加一個帶有ContentPresenter的新選項卡,該選項卡將動態加載視圖及其對應的viewmodel。
所以我的問題是:
1)我應該在這里使用屏幕集合嗎?
2)UserControl應該實現Screen界面嗎?
3)如何告訴MainWindow ViewModel在新添加的選項卡上加載哪個視圖,以保持視圖模型分離?
預先感謝大家。
UPDATE
經過大量閱讀和社區的一些幫助后,我設法解決了這個問題。 這是生成的AppViewModel:
class AppViewModel : Conductor<IScreen>.Collection.OneActive
{
public void OpenTab(Type TipoVista)
{
bool bFound = false;
Screen myScreen = (Screen)Activator.CreateInstance(TipoVista as Type);
myScreen.DisplayName = myScreen.ToString();
foreach(Screen miItem in Items)
{
if (miItem.ToString() == myScreen.ToString())
{
bFound = true;
ActivateItem(miItem);
}
}
if (!bFound) ActivateItem(myScreen);
}
public ObservableCollection<MenuItem> myMenu { get; set; }
public ObservableCollection<LinksItem> myDirectLinks { get; set; }
public ICommand OpenTabCommand
{
get
{
return new RelayCommand(param => this.OpenTab((Type) param), null);
}
}
public AppViewModel()
{
OpenTab(typeof(ClientsViewModel));
MenuModel menu = new MenuModel();
myMenu = menu.getMenu();
myDirectLinks = menu.getLinks();
}
public void CloseTab(Screen param)
{
DeactivateItem(param, true);
}
}
我必須從OpenTabCommand中保留ICommand,因為Caliburn.micro的名稱約定似乎無法在DataTemplate中使用。 希望它可以幫助別人。 謝謝大家
我使用Caliburn.Micro
進行了非常相似的操作,並基於示例附帶的SimpleMDI
示例進行了一些調整以滿足我的需求。
與示例類似,我有一個主要的ShellViewModel
:
public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
{
}
使用包含TabControl
<TabControl x:Name="Items">
的相應ShellView
,將其綁定到Conductor
的Items
屬性。
在這種情況下,我的ShellView
上還有一個ContextMenu
,綁定到(使用Caliburn.Micro
約定)一系列命令,這些命令實例化並Activated
了其他各種ViewModels
(通常使用相應的UserControl
,並使用Conductor
上的ActivateItem
方法。
public class YourViewModel: Conductor<IScreen>.Collection.OneActive
{
// ...
public void OpenItemBrowser()
{
// Create your new ViewModel instance here, or obtain existing instance.
// ActivateItem(instance)
}
}
在那種情況下,我不需要使用任何特定的依賴關系或從程序中的任何其他位置創建ViewModels
。
在其他時候,當我需要從應用程序中的其他地方觸發ViewModel
,我使用了Caliburn.Micro
EventAggregator
來發布自定義事件(例如OpenNewBrowser
),可以通過實現相應接口的類(例如IHandle<OpenNewBrowser>
),因此您的主ViewModel
可以具有一個簡單的Handle
方法來負責打開所需的View
:
public class YourViewModel: Conductor<IScreen>.Collection.OneActive, IHandle<OpenNewBrowser>
{
// ...
public void Handle(OpenNewBrowser myEvent)
{
// Create your new ViewModel instance here, or obtain existing instance.
// ActivateItem(instance)
}
}
我在評論中提到的其他代碼:
有時我會沿着這些方式使用通用方法,以確保如果我已有特定類型屏幕的現有實例,請切換到該實例,否則,請創建一個新實例。
public void ActivateOrOpen<T>() where T : Screen
{
var currentItem = this.Items.FirstOrDefault(x => x.GetType() == typeof(T));
if (currentItem != null)
{
ActivateItem(currentItem);
}
else
{
ActivateItem(Activator.CreateInstance<T>());
}
}
像這樣使用:
public void OpenBrowser()
{
this.ActivateOrOpen<BrowserViewModel>();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.