2015-10-12 40 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 ....