使标签项和棱镜导航相互配合

时间:2018-04-04 22:27:49

标签: c# wpf mvvm prism prism-6

我目前正在编写的应用程序使用Tab Control作为其主要菜单结构。标签允许缓存视图;选中另一个选项卡时,选项卡将保留加载的视图。

每个标签都包含一个区域占位符:

function fetchProductById (id) {
     var db = admin.database()
     var collectionRef = db.ref('server/products')
     var ref = collectionRef.child(id)
     return ref.once('value')
         .then((snapshot) => {
             return snapshot.val()
         })

} 

// then to implement:
fetchProductById('abc')
    .then((result) => {
        console.log('the result is', result)
    })

PRISM提供了通过<TabControl> <TabItem Name="Home"> <ContentControl prism:RegionManager.RegionName="HomeRegion"/> </TabItem> <TabItem Name="Project" Header="Program"> <ContentControl prism:RegionManager.RegionName="ProjectRegion"/> </TabItem> <TabItem Name="TestPlan" Header="Test Plan"> <ContentControl prism:RegionManager.RegionName="TestPlanRegion"/> </TabItem> </TabControl> 界面导航到标签项目,如果新视图中尚未存在,则自动创建视图,或刷新现有标签中的现有视图。

INavigationAware

导航就这样完成了:

public class PersonDetailViewModel : INavigationAware
{
    // Data-Bound property
    public Person SelectedPerson { get; set; }

    // INavigationAware method
    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        var person = navigationContext.Parameters["person"] as Person;
        if (person != null)
            SelectedPerson = person;
    }
}

问题在于:点击标签无法完成常规导航。它只显示已在启动时加载的现有视图。因此,在选择选项卡时,没有机会刷新选项卡。

我想要的行为:我希望标签在首次使用时加载其内容,无论是通过var parameters = new NavigationParameters(); parameters.Add("person", person); if (person != null) _regionManager.RequestNavigate("PersonDetailsRegion", "PersonDetail", parameters); 来电还是点击标签,然后重新使用其内容在后续使用中,包括传递RequestNavigate等参数。

不幸的是,目前,我认为我还有两个不太理想的选择:

  1. 当用户点击标签时模拟Person,可能是通过挂钩标签控件上的RequestNavigate事件。为了实现这一点,我需要将View延迟加载到选项卡中,因为在选项卡上单击时应用RequestNavigate将使选项卡在首次使用时加载两次,从而破坏我可能拥有的任何缓存优势,或者

  2. 使用SelectionChanged到单个区域而不是标签的常规菜单,这些菜单具有简单的优点,但却完全失去了缓存优势。

  3. 关于如何使这项工作的任何想法?

1 个答案:

答案 0 :(得分:0)

  

2.使用RequestNavigate到单个Region而不是制表符的传统菜单,它具有简单的优点,但却完全失去了缓存优势

不是在我尝试的时候......通常情况下,当您重复导航时,该区域会重复使用视图(如果您通过从true返回INavigationAware.IsNavigationTarget来告诉它)和{{1} }可用于更新视图。

示例:

INavigationAware.OnNavigatedTo

依次单击这两个按钮,您将看到只触及一次断点。视图模型和视图将保留并使用新的导航参数进行更新。

如果您从internal class MainWindowViewModel : BindableBase { public MainWindowViewModel( IRegionManager regionManager ) { NavigateCommand = new DelegateCommand<string>( x => regionManager.RequestNavigate( "MainRegion", "PersonView", new NavigationParameters {{"Id", x}} ) ); } public DelegateCommand<string> NavigateCommand { get; } } internal class PersonViewModel : BindableBase, INavigationAware { public PersonViewModel() { Debugger.Break(); } private string _name; public string Name { get { return _name; } set { SetProperty( ref _name, value ); } } public void OnNavigatedTo( NavigationContext navigationContext ) { Name = (string)navigationContext.Parameters[ "Id" ]; } public bool IsNavigationTarget( NavigationContext navigationContext ) { return true; } public void OnNavigatedFrom( NavigationContext navigationContext ) { } } public partial class PersonView : UserControl { public PersonView() { Debugger.Break(); InitializeComponent(); } } <Window x:Class="PrismApplication1.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mvvm="http://prismlibrary.com/" Title="MainWindow" Width="525" Height="350" mvvm:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d"> <DockPanel LastChildFill="True"> <Button Command="{Binding NavigateCommand}" CommandParameter="Person A" Content="Person A" /> <Button Command="{Binding NavigateCommand}" CommandParameter="Person B" Content="Person B" /> <ContentControl mvvm:RegionManager.RegionName="MainRegion" /> </DockPanel> </Window> 返回false,则不会重复使用该视图。