簡體   English   中英

使用Caliburn.Micro MVVM WPF進行視圖導航的建議

[英]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 ,將其綁定到ConductorItems屬性。

在這種情況下,我的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)
    }
}

文檔的這一部分可能會很有用,尤其是“簡單MDI”部分。

我在評論中提到的其他代碼:

有時我會沿着這些方式使用通用方法,以確保如果我已有特定類型屏幕的現有實例,請切換到該實例,否則,請創建一個新實例。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM