Mar*_*del 4 c# mvvm mvvm-light windows-phone-8
我正在尝试将我的 WP8 项目从自制的 MVVM 实现调整为 MVVM Light。我已经成功地完成了这个例子,而且效果很好。然后我开始为我自己的项目重复相同的步骤。
应用程序编译没有错误,但是当我在 Expression Blend 中打开 MainPage.xaml 时,我会收到此错误:
类 project.Services.IDataService 已经注册。App.xaml,第 6 行,第 5 列
如果我查了一下,它是注册 ViewModelLocator 的那一行:
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)
我的 ViewModelLocator.cs:
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
// Create design time view services and models
// see: http://developingux.com/2012/06/10/how-to-fix-error-design-time-data-in-blend-with-mvvm-light/
if (!SimpleIoc.Default.IsRegistered<IDataService>())
{
SimpleIoc.Default.Register<IDataService, DesignDataService>();
}
}
else
{
// Create run time view services and models
if (!SimpleIoc.Default.IsRegistered<IDataService>())
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
}
// only one ViewModel for the MainPage
SimpleIoc.Default.Register<MainViewModel>();
}
Run Code Online (Sandbox Code Playgroud)
从我的代码注释中可以看出,我已经尝试了此处假设的修复程序,但在 Blend 中仍然出现此错误。没有其他地方可以注册 IDataService,那么可能是什么问题?SO 上的其他问题特别针对桌面应用程序,并且也仅包含某种上述修复,其中在注册 ViewModelLocator 之前首先进行检查。
有任何想法吗?:)
更新 1: 我已经设法在 Visual Studio 中显示我的设计时间。我仍然在我的代码隐藏文件中手动引用 DataContext。不过我还是要解决Blend中无法显示设计时数据的问题。从 Visual Studios 的行为来看,它应该可以工作?!
老问题,但仍然相关,我认为原因尚未解释,也没有直接答案。
在设计时,Visual Studio 似乎喜欢多次实例化资源。
这会导致在同一个静态应用程序实例中多次构造一个视图模型定位器,该定位器可能是在您的 App.xaml 或其他一些资源中定义的。
在SimpleIoc.Default横跨这2个视图模型定位器实例的单个实例存在,导致任何新的注册是重复登记。
在重新启动 Visual Studio、重新加载您的项目或终止XDesProc.exe(Visual Studio 中 XAML 设计器的宿主进程)后,它起初似乎可以工作,但是如果您关闭窗口设计器,然后再次打开它,您将获得设计时间错误,因为它正在尝试重新创建链接到该窗口的资源。
我尝试了几种解决方案,例如在视图模型定位器中创建一个静态布尔值,在第一次调用时将其设置为 true,如果在此之前为 true,则返回,并且不注册任何内容。
但不幸的是,这似乎没有帮助,因为布尔值与视图模型定位器一起重新实例化。
可以尝试将它放在一个单独的类中,该类不会在每次打开视图时都重新构建,但这似乎有点傻。
最后,我决定使用.Reset()on 方法SimpleIoc来删除所有以前注册的服务、实例和工厂。
public ViewModelLocator()
{
SimpleIoc.Default.Reset();
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<IExampleService, ExampleServiceImplementation>();
// Register the rest of your services
}
Run Code Online (Sandbox Code Playgroud)
这似乎解决了这个问题,并且在运行时应该没有影响,因为视图模型定位器只会被实例化一次。
| 归档时间: |
|
| 查看次数: |
3831 次 |
| 最近记录: |