Prism Auto ViewModelLocator с подкаталогами в UWP - PullRequest
0 голосов
/ 18 мая 2018

Я не знаю, хорошая ли это практика, но я бы хотел использовать подкаталоги в каталогах "Views" и "ViewModels"

У меня есть этот код прямо сейчас

namespace Project.Universal.ViewModels.Sales
{
    public class SalesListViewModel:ViewModelBase
    {
        // Properties
        private string _test;
        private ICollection<Sale> _sales;

        public string Test
        {
            get => _test;
            set => SetProperty(ref _test, value);
        }

        public ICollection<Sale> Sales {
            get => _sales;
            private set
            {
            }
        }

        // Services
        private readonly IStandardService<Sale> _salesService;

        // Commands
        public DelegateCommand Update { get;}

        // Constructor
        public SalesListViewModel(IStandardService<Sale> salesService)
        {


            Debug.WriteLine(">>>> Initializing SalesListViewModel, trying to set _salesService.");
            _salesService = salesService;

            Debug.WriteLine(">>>> Delegating command to update SalesListViewModel.");
            Update = new DelegateCommand(async () =>
            {
                Sales = await _salesService.GetAsync();
                Test = "Test";
            });
        }

    }
}

А это моя страница просмотра

<mvvm:SessionStateAwarePage
    x:Class="Project.Universal.Views.Sales.SalesListPage"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Project.Universal.Views.Sales"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:mvvm="using:Prism.Windows.Mvvm"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid Margin="{StaticResource MediumLeftTopRightBottomMargin}">
        <TextBlock>this is the Sales page</TextBlock>
        <TextBlock Text="{Binding Test}"></TextBlock>
    </Grid>
</mvvm:SessionStateAwarePage>

Но Prism неправильно внедряет модель представления.Отменив это, Prism Framework внедряет ShellViewModel, как показано ниже:

Ошибка: ошибка пути BindingExpression: свойство «Test» не найдено в «Project.Universal.ViewModels.ShellViewModel».BindingExpression: Path = 'Test' DataItem = 'Project.Universal.ViewModels.ShellViewModel';целевой элемент - «Windows.UI.Xaml.Controls.TextBlock» (Name = 'null');Свойство target - «Текст» (тип «Строка»)

Для организации я хочу использовать этот шаблон для папок:

Views/Context/ViewPage.xaml for views
ViewModels/Context/ViewModel.cs for viewModels

Я использую шаблон из WindowsШаблонная студия с фреймворком Prism 6.3.Извините за мой английский.

1 Ответ

0 голосов
/ 19 мая 2018

Через несколько часов я решил свою проблему:

Windows Template Studio изменила метод ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver() для обеспечения совместимости с другими фреймворками.Я просто изменил этот метод, как я хочу, и это сработало.Для других, у которых будет та же самая проблема, вот код.

Класс App.xaml.cs

    protected override async Task OnInitializeAsync(IActivatedEventArgs args)
        {
            await ThemeSelectorService.InitializeAsync().ConfigureAwait(false);

            ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
            {
                var viewName = viewType.FullName; // get full type name
                var viewModelName = viewName
                    .Substring(0, viewName.Length - 4)
                    .Replace(".Views.", ".ViewModels.");
                var viewModelAssembly = viewType.GetTypeInfo().Assembly.FullName;
                //var viewModel
                var viewModelTypeName = string.Format(CultureInfo.InvariantCulture, "{0}ViewModel, Project.Universal", viewModelName);

                return Type.GetType(viewModelTypeName);
            });
            await base.OnInitializeAsync(args);
        }
...