我有一个相当简单和标准的MVVM WPF应用程序。我使用TinyIoC作为容器来为ViewModel提供底层数据和缓存提供程序。我正在使用TinyIoC,因为我还希望与MonoTouch和Monodroid项目共享此代码。
每个用户控件的ViewModel都不依赖于从TinyIoC解析数据提供程序,它们在添加到MainWindow的XAML时工作正常。
用户控制哪些ViewModel正在使用TinyIoC来解析所使用的数据提供程序获取其数据,在添加到MainWindow时无法在设计器视图中实例化。
重要提示:当我运行应用程序时,一切正常,只是设计师被打破 - 这是一个很大的障碍。
以下是基本代码:
// From App.xaml.cs
private void HandleAppStartupEvent(object sender, StartupEventArgs e) {
IDataStoreProvider store = new XmlDataStoreProvider();
ICacheProvider cache = new DictionaryCacheProvider();
TinyIoCContainer.Current.Register(store);
TinyIoCContainer.Current.Register(cache);
}
View / ViewModel / XAML绑定标准实现 - 这里没什么问题。
在数据层的深处,IoC容器用于解析使用哪个提供程序 - 在上面的代码中设置的提供程序。
public static class Gateway
{
private static IDataStoreProvider store;
private static ICacheProvider cache;
static Gateway() {
store = TinyIoCContainer.Current.Resolve<IDataStoreProvider>();
cache = TinyIoCContainer.Current.Resolve<ICacheProvider>();
}
// use the store and cache here...
}
以下是我从设计师那里得到的确切错误。
无法解析类型:Sample.Core.Data.IDataStoreProvider 在TinyIoC.TinyIoCContainer.ResolveInternal(TypeRegistration注册,NamedParameterOverloads参数,ResolveOptions选项)中的C:_dev \ Sample \ SampleSolution \ Sample.Core \ Utility \ TinyIoC.cs:line 3281 at TinyIoC.TinyIoCContainer.Resolve(Type resolveType)在C:_dev \ Sample \ SampleSolution \ Sample.Core \ Utility \ TinyIoC.cs:第1314行 at TinyIoC.TinyIoCContainer.ResolveResolveType in C:_dev \ Sample \ SampleSolution \ Sample.Core \ Utility \ TinyIoC.cs:line 1433 at C:_dev \ Sample \ SampleSolution \ Sample.Core \ Data \ Gateway.cs中的Sample.Core.Data.Gateway..cctor():第14行
我想我理解为什么会出现这个错误 - 在设计器加载并在MainWindow中执行用户控件之前,不会触发App启动事件来加载IoC。
同样值得注意的是,该应用程序运行良好 - IoC和一切。我想停止设计器加载错误(按优先顺序):
答案 0 :(得分:0)
您是否尝试在Windows /容器加载事件的事件处理程序中加载数据?这样做过去给我造成了这类问题。
答案 1 :(得分:0)
这是第二个项目符号的解决方案(用设计师的模拟数据存取现有的控制数据)
将以下代码添加到ViewModel构造函数中:
public AdminViewModel(UserControl view) {
this.view = view;
var designMode = DesignerProperties.GetIsInDesignMode(view);
if (designMode) {
Items = new ObservableCollection<ItemModel>
{new ItemModel {Name = "Item1"},
new ItemModel {Name = "Item2"}};
}
else {
Items= new ObservableCollection<ItemModel>(Gateway.GetItems());
}
}
虽然有效但我有几个问题:
我更愿意以更清洁的方式使这更“混合”和设计师友好 - 任何其他想法?