2015-10-12 39 views
0

我是Caliburn micro的新手,并试图在Excel加载项中使用它。我实际上使用ExcelDna来实现加载项。我有我的引导程序设置,并能够在对话框中正确运行测试应用程序。一切工作如预期。Caliburn Micro - Excel加载项 - 线程窗口 - NotifyofPropertychanged

然后,我试图在一个单独的线程中运行Window/MainForm,因为我不想让它在各种原因的Excel主线程上运行。然后 NotifyOfPropertyChanged只抛出了CanSayHello以下错误:

{“而调度到UI线程调用时出现错误”} {“调用线程不能因为不同的线程拥有它访问这个对象”}

NotifyOfPropertyChange(()=> Name)可以正常工作,不存在任何问题。

然后我尝试在新线程中初始化boostrapper,这实际上使它工作。但是,如果我关闭了wpf窗口并从excel菜单重新打开,我得到一个错误,我无法初始化boostrapper,因为“已经添加了具有相同密钥的项目”。

有什么建议吗?

弗兰克

代码:

using Caliburn.Micro; 
    using ExcelDna.Integration; 
    using ExcelDNACMTest.ViewModels; 
    using System.Threading; 

    public class myBootstrapper:BootstrapperBase 
     {     
      public myBootstrapper() :base(false) 
      {   
      } 

     } 

     public class ProgramStart : IExcelAddIn //(this is ExcelDNA) 
      { 
       static Thread threadProgramWindow; 
       static readonly MainViewModel ViewModel = new MainViewModel(); 
       static IWindowManager windowManager = new WindowManager(); 

       public void AutoOpen() //ExcelDNA - runs at start of xll 
       { 
        var BS = new myBootstrapper(); 
         BS.Initialize(); 

        var myThread = new Thread(() => 
         { 
          windowManager.ShowDialog(new MainViewModel()); 
         } 
        ); 
        myThread.SetApartmentState(ApartmentState.STA); 
        myThread.Start(); 

       }  
       public void AutoClose() 
       { 
        } 




    //ViewModels 

    class NameViewModel : PropertyChangedBase 
     { 

      string name; 

      public string Name 
      { 
       get { return name; } 
       set 
       { 
        name = value; 

        NotifyOfPropertyChange(() => Name); 
        NotifyOfPropertyChange(() => CanSayHello); //error here    
       } 
      } 

      public bool CanSayHello 
      { 
       get { return !string.IsNullOrWhiteSpace(Name); } 
      } 

      public void SayHello() 
      { 
       MessageBox.Show(string.Format("Hello {0}!", Name)); 
      } 
     } 

public class MainViewModel : Conductor<object> 
{ 
    public void ShowPageOne() 
    { 
     ActivateItem(new NameViewModel()); 
    }   
} 

回答

0

首先你不需要额外的线程。

static IWindowManager windowManager = new WindowManager(); 

呼叫

IOC.Get<IWindowManager>(); 

拿到窗口管理器的.Inizialize()电话后,让您得到正确的窗口管理器。

应该做的伎俩。

from Frank to Frank ....