【问题标题】:Prism : Navigation between different Usercontrols棱镜:不同用户控件之间的导航
【发布时间】:2020-03-31 11:14:36
【问题描述】:

我正在使用棱镜。我有一个视图(DetailMainUC.xaml),它以下列方式保存许多其他视图。

    <UserControl.Resources>
    <DataTemplate x:Key="View1Template" DataType="{x:Type vm:DetailMainUCViewModel}">
        <local:HomeUC />
    </DataTemplate>
    <DataTemplate x:Key="View2Template" DataType="{x:Type vm:DetailMainUCViewModel}">
        <local:WalkAwayBehaviorUC />
    </DataTemplate>
    <DataTemplate x:Key="View3Template" DataType="{x:Type vm:DetailMainUCViewModel}">
        <local:WakeUpOnApproachUC />
    </DataTemplate>
    <DataTemplate x:Key="View4Template" DataType="{x:Type vm:DetailMainUCViewModel}">
        <local:NoLockOnPresenceUC />
    </DataTemplate>
    <DataTemplate x:Key="View5Template" DataType="{x:Type vm:DetailMainUCViewModel}">
        <local:PeekDimmingUC />
    </DataTemplate>
    <DataTemplate x:Key="View6Template" DataType="{x:Type vm:DetailMainUCViewModel}">
        <local:SettingsUC />
    </DataTemplate>
</UserControl.Resources>
<Grid>
    <ContentControl Grid.Column="1" Grid.Row="1" Content="{Binding }">
        <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding SwitchView}" Value="Home">
                        <Setter Property="ContentTemplate" Value="{StaticResource View1Template}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding SwitchView}" Value="Walk Away Behaviour">
                        <Setter Property="ContentTemplate" Value="{StaticResource View2Template}"></Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding SwitchView}" Value="Wake up on approach">
                        <Setter Property="ContentTemplate" Value="{StaticResource View3Template}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding SwitchView}" Value="No lock on presence">
                        <Setter Property="ContentTemplate" Value="{StaticResource View4Template}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding SwitchView}" Value="Peeking and Dimming">
                        <Setter Property="ContentTemplate" Value="{StaticResource View5Template}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding SwitchView}" Value="Settings">
                        <Setter Property="ContentTemplate" Value="{StaticResource View6Template}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>
</Grid>

现在我正在使用事件聚合器在其他区域的不同视图模型之间进行通信。我对上述用户控件的视图模型如下:

public DetailMainUCViewModel(IEventAggregator eventAggregator, HomeViewModel homeViewModel)
{
    this.HomeVM = homeViewModel;
    this._eventAggregator = eventAggregator;
    HomeVM.Initialization(this._eventAggregator);
    this._eventAggregator.GetEvent<MenuClickEvent>().Subscribe(GetMenuName);
    SwitchView = "Home";

}

现在 HomeVM 属性是 HomeViewModel 类型,它是子 DetailMainUCViewModel 的视图模型。像这样,还有许多其他的子视图模型。现在我的问题是我看到 HomeViewModel 的构造函数被调用了两次,并且所有其他子视图模型都发生了同样的情况。 我面临的主要问题是当子视图模型被第二次调用时,eventAggregator 变为空。

DetailsMainUCViewModel 是父视图模型,HomeViewModel 是子视图模型。 DetailMainUC.xaml 以代码部分中提到的方式保存 HomeUC.xaml。 我也写了下面提到的代码

<UserControl.DataContext>
    <vm:HomeViewModel></vm:HomeViewModel>
</UserControl.DataContext>

我怀疑我使用两个地方来附加数据上下文,所以我的视图模型被调用了两次。 在 1.HomeUC.xaml

2.父用户控件DetailMainUC.xaml

但我无法根据需要删除它们。 我的课程设计是 DetailMainUCViewModel 是父视图模型,而 HomeViewModel 是子视图模型。 DetailMainUC.xaml 是父视图,而 HomeUC.xaml 是子视图。一开始我给出的代码 sn-p 来自 DetailMainUC.xaml (它包含所有子用户控件)

除此之外,我还在我已实现 IModule 接口的模块中初始化我的 DetailMainUC.xaml。

public class STDetailOptionsModule : IModule
{
    private readonly IRegionManager _regionManager;
    public STDetailOptionsModule(IRegionManager regionManager)
    {
        this._regionManager = regionManager;
    }

    public void OnInitialized(IContainerProvider containerProvider)
    {
        _regionManager.RegisterViewWithRegion(RegionNames.DetailOptionsRegion, typeof(DetailMainUC));
    }

    public void RegisterTypes(IContainerRegistry containerRegistry)
    {

    }
}

问候

【问题讨论】:

  • 这不是最近删除的问题的副本吗?
  • @Haukinger 你说得对,这是最近删除的问题的副本。我没有找到答案,所以我再次提出了这个问题。这是错的吗 ?我不知道为什么有些版主删除了我的问题。我的问题不合适吗?我仍然不明白,如果一个问题是有效问题,怎么能被删除?

标签: wpf mvvm prism


【解决方案1】:

如果我正确理解了您的问题,那么我可以说您在同一个用户控件中使用多个用户控件通过触发器进行导航。

这种方法是不正确的。 基本上,您希望在各种用户控件之间进行导航。

让我解释一下如何在 Prism 中执行此操作。

this.regionManager.RequestNavigate("your region name where the usercontrol will be put ",
                        navigationPath, NavigationCompleted);

NavigationCompleted 是一个回调方法: navigationPath:是要放置在指定区域的用户控件路径。

希望清楚

正如您所说,您是 prism 新手,所以让我生动地解释一下。

我可以看到您有视图(WalkAwayBehaviorUC、WakeUpOnApproachUC、NoLockOnPresenceUC、PeekDimmingUC、SettingsUC)。 现在让我考虑这些视图在不同的项目中或在同一个项目中,但您希望它们显示在您的区域中,即 RegionNames.DetailOptionsRegion。

现在要做到这一点,您必须将所有导航逻辑放在一个集中位置。 最好的集中位置可能是 shell 。所以 ShellViewModel.cs 是你必须编写导航逻辑的类。

所以创建一个这样的方法:

private void NavigationInitialized(string navigationPath)
    {
        if (string.IsNullOrEmpty(navigationPath))
        {
            throw new Exception();//or send proper message to UI
        }

        this.regionManager.RequestNavigate(RegionNames.DetailOptionsRegion,
                    navigationPath, NavigationCompleted);

    } 

private void NavigationCompleted(NavigationResult  navigationResult)
    {

    }

现在的问题是如何在 ShellViewModel.cs 中获取这个导航名称。 解决方案是 EventAggregator。

在您希望用户控件导航写入的位置。

this.eventAggregator.GetEvent<Navigated>().Publish("WalkAwayBehaviorUC");

现在导航事件类应该是这样的:

public class Navigated : PubSubEvent<string>
{
}

现在您必须在 ShellViewModel.cs 中订阅此导航事件

所以在 ShellViewModel.cs 的构造函数中你必须写:

this.eventAggregator.GetEvent<Navigated>().Subscribe(NavigationInitialized);

【讨论】:

  • 请提供更多信息。我是棱镜的新手。我将不胜感激。
猜你喜欢
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多