【发布时间】:2016-02-15 21:33:52
【问题描述】:
背景
嗨,所有 SO 观众。我通常是一名 Android 开发人员,但现在我正在开发一个针对 WPF 和 Android 的跨平台应用程序。话虽如此,实际上没有关于如何直接做我想做的事情的信息。因此,我最终找到了一个包含 3 部分的博客系列,该系列深入探讨了如何开发基于 Windows 的跨平台 MVVM 项目。只要我将 PCL 设置为与 Xamarin.Android 兼容,任何不会引发错误的代码都应该在我进入 Android 端后工作。以下是博客文章的链接:Blog 1、Blog 2、Blog 3。同样,我使用的是 Android,所以我是为 WPF 应用程序编写代码的新手。
问题
所以我今天的问题只涉及与上述链接的博客文章相关的 PCL-WPF 方面。我尽可能地遵循帖子中列出的每一步。该博客使用 WinRT 和 WinPhone 作为两个目标平台,所以我不得不尝试自己解决问题,以使事情在 WPF 上运行。我必须做的两件事是使用 IsolatedStorage 并基本上使用 WinPhone App.Xaml 进行 WPF 端构建。
我已经完成了博客一直到最后并且构建成功。我什至可以看到我的示例调试行,就像它在第三篇博文末尾谈到的那样。但是,当我运行它时,我得到以下信息:
ActivationException 未被用户代码处理
“Microsoft.Practices.ServiceLocation.ActivationException”类型的异常发生在 GalaSoft.MvvmLight.Extras.dll 中,但未在用户代码中处理
$exception {Microsoft.Practices.ServiceLocation.ActivationException:在缓存中找不到类型:StackOverF.Services.IStorageService。 在 c:\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Extras (PCL)\Ioc\SimpleIoc.cs:line 537 中的 GalaSoft.MvvmLight.Ioc.SimpleIoc.DoGetService(Type serviceType, String key, Boolean cache) 在 GalaSoft.MvvmLight.Ioc.SimpleIoc.GetService(Type serviceType) 在 c:\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Extras (PCL)\Ioc\SimpleIoc.cs:line 789 在 GalaSoft.MvvmLight.Ioc.SimpleIoc.MakeInstanceTClass 在 c:\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Extras (PCL)\Ioc\SimpleIoc.cs:line 729} System.Exception {Microsoft.Practices.ServiceLocation.激活异常}
你们有什么可以告诉我的,也许博客作者跳过了我需要做的事情吗?也许如果向这块“巨石”扔足够多的石头,它就会裂开……
澄清
我的 Visual Studio 解决方案中目前基本上只有两个项目。一种是可移植类库。另一个是 WPF 应用程序。在不久的将来,一旦我在等式的 WPF 方面开始工作,我将使用 Xamarin 中的 PCL 在 Android 项目中重用代码。但是,Android 方面 不是 我的问题的一部分。我只在处理 WPF 项目时遇到了上述问题。
代码(最后编辑于 2016 年 2 月 18 日)
IMainViewModel.cs
using GalaSoft.MvvmLight.Command;
using StackOverF.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StackOverF.ViewModels {
public interface IMainViewModel {
ObservableCollection<Workload> Workload { get; }
RelayCommand RefreshCommand { get; }
RelayCommand AddCommand { get; }
}
}
MainViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using StackOverF.Models;
using StackOverF.Services;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StackOverF.ViewModels {
public class MainViewModel : ViewModelBase,IMainViewModel {
private IDataService dataService;
public MainViewModel(IDataService dataService) {
this.dataService = dataService;
RefreshAsync();
}
private ObservableCollection<Workload> workload = new ObservableCollection<Workload>();
public ObservableCollection<Workload> Workload {
get {
return workload;
}
}
#region Commands
#region Refresh
private RelayCommand refreshCommand;
public RelayCommand RefreshCommand {
get {
return refreshCommand ?? (refreshCommand = new RelayCommand(async () => { await RefreshAsync();}));
}
}
private async Task RefreshAsync() {
workload.Clear();
foreach (Workload listing in await dataService.GetWorkloadAsync()) {
workload.Add(listing);
}
}
#endregion
#region Add
private RelayCommand addCommand;
public RelayCommand AddCommand {
get {
return addCommand ??
(addCommand = new RelayCommand(async () => {
Workload listing = new Workload() { Id = 3, Serial = "relay12" };
await dataService.AddWorkloadAsync(listing);
workload.Add(listing);
}));
}
}
#endregion
#endregion
}
}
LocatorService.cs(DeviceLocatorService,位于 WPF 项目中)
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StackOverF.Services {
public class DeviceLocatorService {
static DeviceLocatorService() {
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic) {
}
else {
}
if (!SimpleIoc.Default.IsRegistered<IStorageService>())
SimpleIoc.Default.Register<IStorageService, StorageService>();
}
public static void Cleanup() {
}
}
}
LocatorService.cs(LocatorService,位于PCL项目中)
using Microsoft.Practices.ServiceLocation;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using StackOverF.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StackOverF.Services {
public class LocatorService {
static LocatorService() {
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
// Services
if (ViewModelBase.IsInDesignModeStatic) {
SimpleIoc.Default.Register<IDataService, Design.DataService>();
}
else {
SimpleIoc.Default.Register<IDataService, Services.DataService>();
}
// View Models
SimpleIoc.Default.Register<IMainViewModel, MainViewModel>();
}
public IMainViewModel MainViewModel {
get {
return ServiceLocator.Current.GetInstance<IMainViewModel>();
}
}
public static void Cleanup() {
}
}
}
return ServiceLocator.Current.GetInstance<IMainViewModel>(); 行出现错误(仅在调试时)。
App.xaml
<Application x:Class="StackOverF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:services="clr-namespace:StackOverF.Services;assembly=StackOverF.PCL"
xmlns:deviceServices="clr-namespace:StackOverF.Services"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<deviceServices:DeviceLocatorService x:Key="Locator.WPF" d:IsDataSource="True" />
<services:LocatorService x:Key="Locator" d:IsDataSource="True" />
</ResourceDictionary>
</Application.Resources>
</Application>
【问题讨论】:
-
适用于 Windows 的 WPF?我不太明白你的目标是什么平台。
-
它是跨平台的。我正在开发的两个平台是适用于 Windows 的 WPF 和适用于 Android 的 Android 哈哈。您在 PCL 中有“通用”代码,可以在两个平台之间共享,同时在他们自己的项目中拥有特定于平台的代码。
-
@Steven_BDawg 你能展示你的 DeviceLocatorService 吗?因为我认为 IStorageService 没有在 IoC 容器中注册。
-
@Valentin 已添加!同样,这是我通过博客 1、博客 2、博客 3 遵循的指南。
-
@Steven_BDawg 能否请您在 DeviceLocatorService ctor 中放置一个断点,在 LocatorService ctor 中放置另一个断点?我认为它在 DeviceLocatorService 的 ctor 之前调用了 LocatorService 的 ctor。在我的机器代码上工作正常。
标签: wpf mvvm-light portable-class-library