UWP 中带有子目录的 Prism Auto ViewModelLocator
Prism Auto ViewModelLocator with Subdirectories in UWP
我不知道这是否是个好习惯,但我想在目录 "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 没有正确注入视图模型。 Unline this,Prism Framework 正在注入 ShellViewModel,就像下面的错误说:
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')
对于组织,我想对文件夹使用这种模式:
Views/Context/ViewPage.xaml for views
ViewModels/Context/ViewModel.cs for viewModels
我使用的模板来自 Windows Template Studio 和 Prism 6.3 框架。
对不起我的英语。
下班后我解决了我的问题:
Windows Template Studio 已更改 ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver()
方法以保持与其他框架的兼容性。我只是按照我的意愿更改了此方法并且有效。对于其他有同样问题的人,这里是代码。
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);
}
我不知道这是否是个好习惯,但我想在目录 "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 没有正确注入视图模型。 Unline this,Prism Framework 正在注入 ShellViewModel,就像下面的错误说:
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')
对于组织,我想对文件夹使用这种模式:
Views/Context/ViewPage.xaml for views
ViewModels/Context/ViewModel.cs for viewModels
我使用的模板来自 Windows Template Studio 和 Prism 6.3 框架。 对不起我的英语。
下班后我解决了我的问题:
Windows Template Studio 已更改 ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver()
方法以保持与其他框架的兼容性。我只是按照我的意愿更改了此方法并且有效。对于其他有同样问题的人,这里是代码。
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);
}