I'm new to Caliburn micro and am trying to use it in an Excel add-in. I'm actually using ExcelDna to realize the add-in. I have my bootstrapper setup and am able to run a test application correctly in a dialog. Everything works like expected.
I then tried to run the Window/MainForm in a separate thread since I don't want it to run on Excel's main thread for various reasons. NotifyOfPropertyChanged throws then the following error only for the CanSayHello:
{"An error occurred while dispatching a call to the UI Thread"} {"The calling thread cannot access this object because a different thread owns it."}
NotifyOfPropertyChange(() => Name) works correctly w/o any issues.
I then tried to initialize the boostrapper in the new thread and this actually makes it work. However, if I close the wpf window and reopen from my excel menu i get an error that I cannot initialize the boostrapper since "An item with the same key has already been added".
Any suggestions?
Frank
Code:
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());
}
}