0

我对在 Prism 中实现这一点感到很困惑。我在一个班轮中的场景是如何在一个视图中实现 Prism Navigation (regionManager.RequestNavigate),该视图在主窗口上显示为单独的模态/非模态窗口。

这篇文章中获取一些代码,我现在可以显示一个单独的窗口,但我对在显示的窗口区域中导航感到非常困惑。我将尝试在下面放置一些代码来澄清我的情况。

RoomBandViewModel中的这段代码启动对话框

private void ManageRoomFacility() {
    dialogService.ShowDialog<RoomFacilityMainWindowView>(this, container.Resolve<RoomFacilityMainWindowView>());
    regionManager.RequestNavigate(RegionNames.Main_Region, new Uri("RoomFacilityMainView", UriKind.Relative));

可以看出,我启动了显示视图的对话框(代码如下所示),然后尝试在视图的区域之一中导航

弹出窗口RoomFacilityMainWindowView

<Window x:Class="HotelReservation.Main.View.RoomFacilities.RoomFacilityMainWindowView"

    <view:RoomFacilityMainView 
        prism:RegionManager.RegionName="{x:Static const:RegionNames.Window_Main_Region}"/>

</Window>

窗口内的 UserControl ( RoomFacilityMainView )

<UserControl x:Class="HotelReservation.Main.View.RoomFacilities.RoomFacilityMainView"
    <Grid VerticalAlignment="Stretch" >
        ...
        <Border Grid.Column="0" Style="{StaticResource RegionBorderStyle}">
            <StackPanel>
                <TextBlock Text="Some Sample Text"/>
                <ContentControl prism:RegionManager.RegionName="{x:Static const:RegionNames.Window_List_Region}"
                            />
            </StackPanel>
        </Border>

        <GridSplitter Width="5" Grid.Column="1" HorizontalAlignment="Stretch" />

        <Border Grid.Column="2" Style="{StaticResource RegionBorderStyle}" >
            <TabControl x:Name="Items" Margin="5" prism:RegionManager.RegionName="{x:Static const:RegionNames.Window_Edit_Region}"  />
        </Border>

    </Grid>
</UserControl>

后面的代码 ( RoomFacilityMainView.xaml.cs )

public partial class RoomFacilityMainView : UserControl {

    public RoomFacilityMainView() {
        InitializeComponent();

        RoomFacilityMainViewModel viewModel = this.DataContext as RoomFacilityMainViewModel;
        if (viewModel == null) {
            viewModel = ServiceLocator.Current.GetInstance<RoomFacilityMainViewModel>();
            this.DataContext = viewModel;
        }
    }
}

RoomFacilityMainViewModel 公共类 RoomFacilityMainViewModel : BindableBase {

    IRegionManager regionManager;
    IUnityContainer container;

    public RoomFacilityMainViewModel(IRegionManager regionManager, IUnityContainer container) {
        this.regionManager = regionManager;
        this.container = container;

        regionManager.RequestNavigate(RegionNames.Window_List_Region, new Uri("RoomFacilityListView", UriKind.Relative));

    }
}

使用此代码不会发生导航,我只会得到一个空白窗口。RoomFacilityListView.xaml 的内容应该显示,但它是空白的。

如果代码令人困惑,那么请就如何使用具有区域但通过 Dialog Service 显示为单独窗口而不是 MainWindow(Shell) 的 View 导航(使用 RequestNavigate)提供建议。

4

1 回答 1

0

如果您正在使用IDialogService通过方法显示新窗口的实现Window.ShowDialog(),那么您的导航不起作用也就不足为奇了。该ShowDialog()方法仅在关闭窗口时返回,因此您的导航请求实际上将在关闭的窗口上处理,特别是窗口关闭后。

模态窗口中没有什么特别的东西会阻止使用 Prism 区域和在其中导航。一个限制是您不能“按原样”创建多个窗口实例,因为它们都有同名的区域,而使用一个区域管理器是不可能的。但是,有一个解决方案:作用域区域管理器。

假设您不打算创建多个实例,这里有一个示例如何解决您的问题。

首先,您必须确保您的模态对话框RegionManager与您的主对话框的实例相同RegionManager(我在这里使用 MEF,但实际上没关系):

[Export]
public partial class Dialog : Window
{
    private readonly IRegionManager rm;

    [ImportingConstructor]
    public Dialog(IRegionManager rm)
    {
        this.InitializeComponent();
        this.rm = rm;

        // Don't forget to set the attached property to the instance value
        RegionManager.SetRegionManager(this, this.rm);
    }
}

现在,使用接受导航回调的方法扩展您的对话服务实现:

bool? ShowDialog<T>(object ownerViewModel, object viewModel, Action initialNavigationCallback = null) where T : Window
{

    Window dialog = /* your instance creation code, e.g. using container */;
    dialog.Owner = FindOwnerWindow(ownerViewModel);
    dialog.DataContext = viewModel;

    if (initialNavigationCallback != null)      
    {
        dialog.Loaded += (s, e) => initialNavigationCallback();
    }

    return dialog.ShowDialog();
}

这将为您提供显示带有初始导航请求的对话框的可能性,您可以这样调用它:

void ManageRoomFacility() {
    dialogService.ShowDialog<RoomFacilityMainWindowView>(
        this, 
        container.Resolve<RoomFacilityMainWindowView>(),
        () => regionManager.RequestNavigate(
            RegionNames.Main_Region, 
            new Uri("RoomFacilityMainView", UriKind.Relative))
        );

或者,您可以为您的任务使用基于状态的导航基于状态的导航快速入门中有一个发送消息模式对话框的示例实现。

<prism:InteractionRequestTrigger SourceObject="{Binding SendMessageRequest}">
    <prism:PopupWindowAction IsModal="True"> 
        <prism:PopupWindowAction.WindowContent>
            <vs:SendMessagePopupView />
        </prism: PopupWindowAction.WindowContent>
    </prism:PopupWindowAction>
</prism:InteractionRequestTrigger>
于 2015-04-02T08:24:51.113 回答