0

我有一个相当简单和标准的 MVVM WPF 应用程序。我使用 TinyIoC 作为容器来为 ViewModel 提供底层数据和缓存提供程序。我正在使用 TinyIoC,因为我还想与 MonoTouch 和 Monodroid 项目共享此代码。

当添加到 MainWindow 的 XAML 时,每个 ViewModel 不依赖于解析来自 TinyIoC 的数据提供程序的用户控件都可以正常工作。

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

}

这是我从设计师那里得到的确切错误。

无法解析类型:TinyIoC.TinyIoCContainer.ResolveInternal 中的 Sample.Core.Data.IDataStoreProvider(TypeRegistration 注册,NamedParameterOverloads 参数,ResolveOptions 选项)在 C:_dev\Sample\SampleSolution\Sample.Core\Utility\TinyIoC.cs:line 3281 at TinyIoC.TinyIoCContainer.Resolve(Type resolveType) in C:_dev\Sample\SampleSolution\Sample.Core\Utility\TinyIoC.cs: 第 1314 行 TinyIoC.TinyIoCContainer.ResolveResolveType in C:_dev\Sample\SampleSolution\Sample.Core\Utility \TinyIoC.cs:C:_dev\Sample\SampleSolution\Sample.Core\Data\Gateway.cs 中 Sample.Core.Data.Gateway..cctor() 的第 1433 行:第 14 行

我想我明白为什么会出现此错误 - 在设计器加载并执行 MainWindow 内的用户控件之前,不会触发 App 启动事件以加载 IoC。

再次需要注意的是,该应用程序运行良好 - IoC 和一切。我想通过以下任一方式(按优先顺序)停止设计器加载错误:

  • 了解如何修复代码以与设计人员一起正常工作
  • 为设计人员使用模拟数据存根现有的控制数据
  • 禁用此设计器功能
4

2 回答 2

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

虽然有效,但我有几个担忧:

  • 使用非应用逻辑污染代码
  • 强制我将 View 的引用传递给 ViewModel

我更愿意以更简洁的方式使这个更“可混合”和设计师友好——还有其他想法吗?

于 2012-07-13T22:03:04.637 回答
0

您是否尝试在 Windows/容器加载事件的事件处理程序中加载数据?这样做在过去给我造成了这种类型的问题。

于 2012-07-13T18:53:54.290 回答