代码之家  ›  专栏  ›  技术社区  ›  JamesStuddart

重置使用MEF加载的控件

  •  2
  • JamesStuddart  · 技术社区  · 14 年前

    我已经使用MEF加载外部xap,这很好。 但是,当我使用加载的控件离开页面,然后返回到该页面时,该控件正处于我离开它时的状态。

    有时候这很好,但对我正在做的项目来说不是。

    控件已成功加载到以下位置:

     <ItemsControl x:Name="content"/>
    

    这在XAML标记中

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        content.Items.Clear();
    }
    

    这成功地移除了控件,就像添加之前一样,当我回到页面时,它崩溃了,告诉我控件已经是元素的子元素。

    以下是整页代码:

    public partial class Wizard : IPartImportsSatisfiedNotification
    {
        public Wizard()
        {
            InitializeComponent();
            CompositionInitializer.SatisfyImports(this);
    
            var controlToLoad = IsolatedStorageHelper.GetValue("control");
    
            if (!String.IsNullOrEmpty(controlToLoad))
            {
                CatalogService.AddXap(controlToLoad + ".xap");
            }
        else
        {
            NavigationService.Navigate(new Uri("/ServiceSelector", UriKind.Relative));
        }
    }
    
    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        content.Items.Clear();
    }
    
    [Import]
    public IDeploymentCatalogService CatalogService { get; set; }
    
    [ImportMany(AllowRecomposition = true)]
    public Lazy<UserControl>[] MefModuleList { get; set; }
    
    #region IPartImportsSatisfiedNotification Members
    
    public void OnImportsSatisfied()
    {
        MefModuleList.ToList()
            .ForEach(module =>
                content.Items.Add(module.Value)
            );
    }
    
    #endregion
    }
    

    有什么想法吗?

    谢谢,

    1 回复  |  直到 14 年前
        1
  •  1
  •   15ee8f99-57ff-4f92-890c-b56153    14 年前

    一个简单的解决方法是使用ExportFactory而不是Lazy来避免整个问题:创建一个新实例而不是重用旧实例。只需确保丢弃的实例得到GC,而不是堆积(编辑:新实例在ExportLifetimeContext实例中交给您,该实例管理对象的生命周期)。

    现在出了什么问题,听上去老孩子还以为自己有父母。在你再次把他放回容器之前(最好是在你把他移走的时候),你需要告诉他他现在已经没有父母了。不过,UserControl.Parent是只读的。可能会给父母打电话给RemoveLogicalChild?我还没有测试过,但如果出口工厂的好笑没有让你的船漂浮起来,那么通用大道似乎值得一探究竟。