0

I don't know if it is a good pratice, but I would like to use subdirectories into the directories "Views" and "ViewModels"

I have this code right now

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";
            });
        }

    }
}

And this is my view page

<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>

But Prism do not inject the view model correctly. Unline this, the Prism Framework is injecting ShellViewModel, like error bellow says:

Error: BindingExpression path error: 'Test' property not found on 'Project.Universal.ViewModels.ShellViewModel'. BindingExpression: Path='Test' DataItem='Project.Universal.ViewModels.ShellViewModel'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')

For organization, I want to use this pattern for folders:

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

I'm using a template from Windows Template Studio with Prism 6.3 framework. Sorry for my english.

Raul Medeiros
  • 177
  • 2
  • 9
  • 2
    Hi, I guess the directories aren't the problem, but your namespace… could you try to use ...ViewModels and …Views? otherwise you need to modify the way to scan for your classes. But I'm not sure how to do it... – thezapper May 18 '18 at 18:38
  • Oh, yes, I change the way I scan for classes. I'll post my solution, thanks. – Raul Medeiros May 19 '18 at 13:34

1 Answers1

1

After hours I've resolute my problem:

The Windows Template Studio have changed the ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver() method to mantain compatibility to others frameworks. I've just changed this method like I want and that worked. For others that will have same problem, here's the code.

Class 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);
        }
Raul Medeiros
  • 177
  • 2
  • 9