为什么MEF Lazy加载不能在ViewModel中工作?

时间:2012-01-30 23:48:36

标签: wpf mvvm mef lazy-loading

我正在尝试让Lazy在我绑定的ViewModel中为一个集合工作。该集合通过MEF加载正常,但永远不会显示在绑定的UI中。

以下是用户界面:

<Window x:Class="TestWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

     <StackPanel>
          <ItemsControl ItemsSource="{Binding MyList}">
               <ItemsControl.ItemTemplate>
                    <DataTemplate>
                         <Label Content="{Binding ItemTitle}" />
                    </DataTemplate>
               </ItemsControl.ItemTemplate>
          </ItemsControl>
     <StackPanel>
</Window>

代码隐藏类:

public partial class TestWindow : Window
{
     public TestWindow()
     {
          InitializeComponent();
          this.DataContext = new TestVM();
     }
}

ViewModel:

public class TestVM : INotifyPropertyChanged, IPartImportsSatisfiedNotification
{
     public TestVM()
     {
          //I'm using a static class to initiate the import
          CompositionInitializer.SatisfyImports(this);
     }

     public event PropertyChangedEventHandler PropertyChanged = delegate { };

     [ImportMany(typeof(MyItemBase))]
     public Lazy<MyItemBase>[] MyList { get; set; }

     public void OnImportsSatisfied()
     {
          this.PropertyChanged(this, new PropertyChangedEventArgs("MyList"));
     }
}

项目的基类和一些继承的测试类:

[InheritedExport]
public class MyItemBase
{
    public MyItemBase()
    {

    }

    public string ItemTitle{ get; set; }
}

public class MyItem1: MyItemBase
{
    public MyItem1()
    {
        this.ItemTitle = "Item 1";
    }
}

public class MyItem2: MyItemBase
{
    public MyItem2()
    {
        this.ItemTitle = "Item 2";
    }
}

如果我只是删除延迟加载,这是有效的。但是,我稍后需要应用一些导出属性,这意味着要进入Lazy。

1 个答案:

答案 0 :(得分:2)

问题是你想要绑定到MyItembase对象的列表,但你的实际绑定是一个懒惰的MyItembase对象的arrray。(只要你从来没有为你的懒项目调用.Value就不会发生任何事情)

我的项目我为mef使用私有惰性集合,为wpf使用正常的ObservableCollection。顺便说一句,我更喜欢你的Mef导入的构造函数注入

public class TestVM : INotifyPropertyChanged, IPartImportsSatisfiedNotification
{
 public TestVM()
 {
      //I'm using a static class to initiate the import
      CompositionInitializer.SatisfyImports(this);

      this.MyList = new ObservableCollection();
      foreach(var lazyitem in _mefList)
      {
          this.MyList.Add(lazyitem.Value);
      }
 }

 public event PropertyChangedEventHandler PropertyChanged = delegate { };

 public ObservbableCollection<MyItemBase> MyList{ get; set; }

 [ImportMany(typeof(MyItemBase))]
 private IEnumarable<Lazy<MyItemBase>> _mefList { get; set; }

 public void OnImportsSatisfied()
 {
      //this.PropertyChanged(this, new PropertyChangedEventArgs("MyList"));
 }

}