【问题标题】:Get RegionManager in ViewModel在 ViewModel 中获取 RegionManager
【发布时间】:2021-12-06 15:10:48
【问题描述】:

在我的项目中,我将 Prism 用于视图和视图模型。我现在想将另一个视图加载到 MainWindowView 中的 UserControl 中。我读到我可以这样做:

_regionManager.RegisterViewWithRegion("MainRegion", typeof(View));

但不幸的是,我不知道如何在我的 ViewModel 中访问 IRegionManger 的实例。在我找到的所有示例中,都使用了其他变量,但没有显示它们的来源。

这是我的观点:

<Window x:Class="PortfolioVisualizer.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:local="clr-namespace:PortfolioVisualizer"
        mc:Ignorable="d"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="15*"/>
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0">
            <Button Command="{Binding NavigateCommand}" CommandParameter="AddAssetView">
                <StackPanel>
                    <Image/>
                    <Label Content="Add Asset"/>
                </StackPanel>
            </Button>
            <Button Command="{Binding NavigateCommand}" CommandParameter="ConfigView">
                <StackPanel>
                    <Image/>
                    <Label Content="Settings"/>
                </StackPanel>
            </Button>
        </StackPanel>

        <Grid Grid.Column="1">
            <ContentControl prism:RegionManager.RegionName="MainRegion"/>
        </Grid>

    </Grid>
</Window>

这是我的视图模型:

public class MainWindowViewModel : ViewModelBase
    {
        private readonly IRegionManager _RegionManager;

        public DelegateCommand<string> NavigateCommand;
        

        public MainWindowViewModel(IRegionManager regionManager)
        {
            _RegionManager = regionManager;
            NavigateCommand = new DelegateCommand<string>(ExecuteNavigateCommand);
            _RegionManager.RegisterViewWithRegion("MainRegion", typeof(DashboardView));
        }

        private void ExecuteNavigateCommand(string viewName)
        {
            if (string.IsNullOrWhiteSpace(viewName))
                return;

            _RegionManager.RequestNavigate("ContentRegion", viewName);
        }
    }

这是 ViewModdelBase

public class ViewModelBase : BindableBase
    {
        public ViewModelBase()
        {
        
        }
    }

(我知道ViewModelBase只是画蛇添足,但后面有东西)

【问题讨论】:

    标签: c# wpf mvvm navigation prism


    【解决方案1】:

    您让容器像任何其他依赖项一样注入区域管理器:

    internal class MyViewModel
    {
        public MyViewModel( IRegionManager regionManager )
        {
            regionManager.DoSomeStuff(); // or just put it into a field for later use
        }
    }
    

    请注意,如果您不在代码或 xaml 中手动 new 视图模型,这只会自动工作。相反,如果您先查看模型(大部分时间推荐),请使用本身注入的工厂(例如Func&lt;MyViewModel&gt; myViewModelFactory)创建它,或者使用Prism的ViewModelLocator将其创建为数据上下文,如果您查看 -首先。

    【讨论】:

    • @arne ViewModelLocator.AutoWireViewModel=true 就足够了 - 假设您的视图位于 Views 命名空间中,而视图模型位于 ViewModels 中,并且它们具有共同的基本名称,例如MySpecialViewMySpecialViewModel。如果您不喜欢约定方法,您也可以向视图模型提供者注册视图/视图模型对(尽管它非常好)。
    • 如何创建视图模型?视图模型定位器将使用容器并提供所有参数。如果你手动调用你的构造函数,你必须自己提供它们。
    • @arne 您发布的 xaml 只是开始标签 - 例如,我们看不到那里是否有 &lt;Window.DataContext&gt;&lt;viewModels:MainWindowViewModel/&gt; 也是一个构造函数调用。另请注意,视图必须驻留在 Views 命名空间中,并在 ViewModels 中查看模型,以便默认约定起作用。
    • 您使用Resolve&lt;MainWindow&gt;() 创建MainWindow?然后,这应该使用默认的PrismApplications。您的设置中是否调用了ConfigureViewModelLocator,即那里是否有断点?
    • 如果ConfigureViewModelLocator 没有被调用并且你没有手动设置视图模型工厂,Prism 默认使用Activator.CreateInstance,它不能注入任何东西并且会解释你所看到的异常。见代码here。您使用哪个容器、prism 应用程序、引导程序等?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 2017-09-07
    • 2021-08-20
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    • 1970-01-01
    相关资源
    最近更新 更多