Новая оболочка / окно в Prism / WPF показывает неправильный вид - PullRequest
1 голос
/ 27 мая 2019

Вдохновленный этим ответом , я создал оболочку общего назначения (Prism, WPF) следующим образом:

<Window x:Class="VRMDataLogger.UI.Shell" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" Title="My App" Height="450" Width="800">
    <Grid>
        <ContentControl prism:RegionManager.RegionManager="{Binding RegionManager}" prism:RegionManager.RegionName="MainShellRegion" />
    </Grid>
</Window>
public partial class Shell : Window
{
    public Shell(IRegionManager regionManager, Type contentType)
    {
        RegionManager = regionManager;
        InitializeComponent();
        RegionManager.RegisterViewWithRegion("MainShellRegion", contentType);
    }

    public IRegionManager RegionManager { get; }
}

Начальная оболочка создается в App.CreateShell():

protected override Window CreateShell()
{
    return new Shell(Container.Resolve<IRegionManager>(), typeof(StartScreen));
}

Это прекрасно работает, и в исходной оболочке отображается правильный вид.

Затем я пытаюсь создать вторую оболочку из StartScreenViewModel, которая показывает другое представление:

var shell = new Shell(RegionManager.CreateRegionManager(), typeof(MainScreen));
shell.Show();

Это открывает новое окно, но показывает тот же вид, что и первое окно (StartScreen) вместо MainScreen. Что я тут не так делаю?

Ответы [ 2 ]

0 голосов
/ 27 мая 2019

Так что я тоже думал о том, чтобы избавиться от всего этого.Но я думаю, что в результате я потеряю приятную особенность внедрения зависимостей в мои модели представлений

Совсем нет.Фактически, вы получаете больший контроль над тем, как создаются ваши модели представления.

При первом просмотре модель представления обычно создается с помощью ViewModelLocator при навигации и затем передается NavigationParameters, если таковые имеются.

Если вы создаете модель представления вручную и связываете представление с помощью шаблонов данных, вы получаете полный контроль над созданием модели представления.Самый простой вариант - ввести фабрику для моделей представлений (например, Func<MainScreenViewModel>), и вы получите полную инъекцию зависимостей из контейнера.

internal class StartScreenViewModel
{
    public StartScreenViewModel( Func<MainScreenViewModel> mainScreenViewModelFactory )
    {
        GoToMainScreenCommand = new DelegateCommand( () => new Shell( mainScreenViewModelFactory() ).Show() );
    }

    public DelegateCommand GoToMainScreenCommand { get; }
}

Конечно, вы можете использовать более изощренный, созданный вручнуюЗаводской, если это необходимо (см. этот ответ ).

0 голосов
/ 27 мая 2019

Попробуйте использовать уникальное имя региона для каждой оболочки:

public partial class Shell : Window
{
    public Shell(IRegionManager regionManager, Type contentType)
    {
        RegionManager = regionManager;
        InitializeComponent();
        MainRegionName = Guid.NewGuid().ToString();
        RegionManager.RegisterViewWithRegion(MainRegionName, contentType);
    }

    public string MainRegionName { get; }
    public IRegionManager RegionManager { get; }

}

XAML:

<ContentControl prism:RegionManager.RegionManager="{Binding RegionManager}"
                prism:RegionManager.RegionName="{Binding MainRegionName, RelativeSource={RelativeSource AncestorType=Window}}" />
...