Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF PRISM:IRegionMemberLifetime KeepAlive不会被调用_Wpf_Silverlight_Mvvm_Prism - Fatal编程技术网

WPF PRISM:IRegionMemberLifetime KeepAlive不会被调用

WPF PRISM:IRegionMemberLifetime KeepAlive不会被调用,wpf,silverlight,mvvm,prism,Wpf,Silverlight,Mvvm,Prism,我需要根据特定条件切换正在显示的视图。 我已经在ViewModel的构造函数中实现了切换逻辑 我正在视图上实现IRegionMemberLifetime,并将KeepAlive设置为false,以便始终获得视图和ViewModel的新实例 但是由于某种原因,当我点击导航按钮时,我在KeepAlive的断点从未到达,我得到的是MainView而不是WelcomeView 以下是代码供您参考: 导航按钮: 视图: [RegionMemberLifetimeKeepAlive=false] 公共部分类

我需要根据特定条件切换正在显示的视图。 我已经在ViewModel的构造函数中实现了切换逻辑

我正在视图上实现IRegionMemberLifetime,并将KeepAlive设置为false,以便始终获得视图和ViewModel的新实例

但是由于某种原因,当我点击导航按钮时,我在KeepAlive的断点从未到达,我得到的是MainView而不是WelcomeView

以下是代码供您参考:

导航按钮:

视图:

[RegionMemberLifetimeKeepAlive=false] 公共部分类主视图:UserControl,IMainView { 公共主视图IMAINVIEWMODEL主视图模型 { 初始化组件; ViewModel=mainViewModel; } 公共IViewModel视图模型 { 获取{return IViewModel DataContext;} 设置{DataContext=value;} } } 外壳视图模型:

公共类ShellViewModel:ViewModel、IShellViewModel { 私有只读IRegionManager _regionManager; 公共ShellViewModelIRegionManager区域管理器 { _regionManager=regionManager; NavigateCommand=新的DelegateCommandNavigate; ApplicationCommand.NavigateCommand.RegisterCommandNavigateCommand; } 私有void Navigateobject navigatePath { 如果navigatePath!=null { _regionManager.RequestNavigateRegions.Main、navigatePath.ToString; } } public DelegateCommand NavigateCommand{get;private set;} }
您可以查看Prism库中的RegionMemberLifetimeBehavior类,它位于C:\Prism4\PrismLibrary\Desktop\Prism\Regions\Behaviors

IRegionMemberLifetime接口和RegionMemberLifeTime属性都完成了相同的任务,可以在视图或ViewModel上定义,前提是ViewModel设置为DataContext

以下是相关的代码:

private void OnActiveViewsChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // We only pay attention to items removed from the ActiveViews list.
        // Thus, we expect that any ICollectionView implementation would
        // always raise a remove and we don't handle any resets
        // unless we wanted to start tracking views that used to be active.
        if (e.Action != NotifyCollectionChangedAction.Remove) return;

        var inactiveViews = e.OldItems;
        foreach (var inactiveView in inactiveViews)
        {
            if (!ShouldKeepAlive(inactiveView))
            {
                this.Region.Remove(inactiveView);
            }
        }
    }

    private static bool ShouldKeepAlive(object inactiveView)
    {
        IRegionMemberLifetime lifetime = GetItemOrContextLifetime(inactiveView);
        if (lifetime != null)
        {
            return lifetime.KeepAlive;
        }

        RegionMemberLifetimeAttribute lifetimeAttribute = GetItemOrContextLifetimeAttribute(inactiveView);
        if (lifetimeAttribute != null)
        {
            return lifetimeAttribute.KeepAlive;
        }

        return true;
    }

我甚至能够分步编写这段代码,以查看它如何与我的应用程序交互。为了回答您的问题,如果您的KeepAlive属性没有被命中,那么它就不会从ActiveView中删除。另外,如果要通过IoC从容器解析视图,请确保尚未将其注册为单例类型,每次解析时都会获得一个新实例。属性/接口只会将其从区域中完全删除,不能保证您获得一个新实例。

您可以查看Prism库中的RegionMemberLifetimeBehavior类,该类位于C:\Prism4\PrismLibrary\Desktop\Prism\Regions\Behaviors

IRegionMemberLifetime接口和RegionMemberLifeTime属性都完成了相同的任务,可以在视图或ViewModel上定义,前提是ViewModel设置为DataContext

以下是相关的代码:

private void OnActiveViewsChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // We only pay attention to items removed from the ActiveViews list.
        // Thus, we expect that any ICollectionView implementation would
        // always raise a remove and we don't handle any resets
        // unless we wanted to start tracking views that used to be active.
        if (e.Action != NotifyCollectionChangedAction.Remove) return;

        var inactiveViews = e.OldItems;
        foreach (var inactiveView in inactiveViews)
        {
            if (!ShouldKeepAlive(inactiveView))
            {
                this.Region.Remove(inactiveView);
            }
        }
    }

    private static bool ShouldKeepAlive(object inactiveView)
    {
        IRegionMemberLifetime lifetime = GetItemOrContextLifetime(inactiveView);
        if (lifetime != null)
        {
            return lifetime.KeepAlive;
        }

        RegionMemberLifetimeAttribute lifetimeAttribute = GetItemOrContextLifetimeAttribute(inactiveView);
        if (lifetimeAttribute != null)
        {
            return lifetimeAttribute.KeepAlive;
        }

        return true;
    }

我甚至能够分步编写这段代码,以查看它如何与我的应用程序交互。为了回答您的问题,如果您的KeepAlive属性没有被命中,那么它就不会从ActiveView中删除。另外,如果要通过IoC从容器解析视图,请确保尚未将其注册为单例类型,每次解析时都会获得一个新实例。属性/接口只会将其从区域中完全删除,不能保证获得新的实例。

显示NavigateCommand的代码以及如何导航。@Zabavsky:我已为处理navigate命令的ShellViewModel添加了代码。您可以将Views:MainView作为CommandParameter传递并导航到它。要访问KeepAlive,您应该从主视图导航。我想您可能可以像这样对视图模型进行属性设置:[RegionMemberLifetimeKeepAlive=false]@Zabavsky:您建议在我的代码中进行什么更改以获得我想要的行为?您能提供一个示例代码吗?显示NavigateCommand的代码以及如何导航。@Zabavsky:我已经为处理navigate命令的ShellViewModel添加了代码。您可以将Views:MainView作为CommandParameter传递并导航到它。要访问KeepAlive,您应该从主视图导航。我想您可能可以像这样对视图模型进行属性设置:[RegionMemberLifetimeKeepAlive=false]@Zabavsky:您建议在我的代码中进行什么更改以获得我想要的行为?你能给我提供一个示例代码吗?进一步的评论。为什么要将视图传递到ViewModel?我将视图传递到ViewModel,以便将视图的ViewModel属性设置为this,但这并不能真正解释为什么ViewModel需要对视图进行硬引用。通常,ViewModel与视图无关。更新:使用视图优先的方法。进一步注释。为什么要将视图传递到ViewModel?我将视图传递到ViewModel,以便可以设置
这并不能真正解释为什么ViewModel需要对视图进行硬引用。通常,ViewModel与视图无关。更新:使用视图优先的方法。