好的,我遇到了解决这个问题的问题。我找到的大多数教程要么不完整,要么不能很好地解释这个过程。
我使用Caliburn.Micro创建了一个测试WPF应用程序,该应用程序的主窗口(ShellViewModel)有一个文本框和一个按钮,该按钮打开第二个窗口,其中包含一个文本框和另一个按钮。当用户在第二个窗口中添加文本并单击"发送" POCO对象已创建,应发送到第一个窗口并显示在ShellViewModel的文本框中。
我不确定我哪里出错,似乎没有很多文章可以帮助解决这个问题。
我尝试使用以下文章寻求帮助: https://claytonone.wordpress.com/2014/06/14/caliburn-micro-part-1-getting-started/
https://caliburnmicro.com/documentation/event-aggregator
******编辑 - 按照指示对上述项目进行了重新编程 https://caliburnmicro.com/documentation/event-aggregator 以下是该项目的代码。注意我添加了一个POCO类来存储和发送我想要发送到另一个窗口的数据,这更像是我在我正在进行的主要项目中的最终目标。
我现在遇到的问题: 1.当我运行本教程设计的程序时,VS Errored说没有无参数构造函数。为此,我尝试添加构造函数。现在程序运行了。 2.当我在第二个窗口中键入文本并单击发送时,我得到一个"空引用错误",如果我调试" ToSend"创建对象并使用正确的数据填充对象。
AppBootStrapper:
namespace CaliburnMicro
{
class AppBootstrapper : BootstrapperBase
{
private readonly SimpleContainer _container = new SimpleContainer();
public AppBootstrapper()
{
Initialize();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<ShellViewModel>();
}
protected override void Configure()
{
_container.Singleton<IEventAggregator, EventAggregator>();
}
}
}
ShellViewModel:
namespace CaliburnMicro.ViewModels
{
class ShellViewModel : Screen, IHandle<EventMessage>
{
private string _messageBox;
private readonly IEventAggregator _eventAggregator;
public string MessageBox
{
get { return _messageBox; }
set
{
_messageBox = value;
NotifyOfPropertyChange(() => MessageBox);
}
}
public ShellViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.Subscribe(this);
}
public ShellViewModel()
{
}
public void OpenWindow()
{
WindowManager wm = new WindowManager();
SecondWindowViewModel swm = new SecondWindowViewModel(_eventAggregator);
wm.ShowWindow(swm);
}
public void Handle(EventMessage message)
{
MessageBox = message.Text;
}
}
}
SecondWindowViewModel
namespace CaliburnMicro.ViewModels
{
class SecondWindowViewModel: Screen
{
private string _secondTextBox;
private readonly IEventAggregator _eventAggregator;
public EventMessage Tosend = new EventMessage();
public string SecondTextBox
{
get { return _secondTextBox; }
set
{
_secondTextBox = value;
NotifyOfPropertyChange(() => SecondTextBox);
}
}
public SecondWindowViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
public void SendBack()
{
Tosend.Text = SecondTextBox;
_eventAggregator.PublishOnUIThread(Tosend);
Thread.Sleep(1000); //I wanted the app to wait a second before closing
TryClose();
}
}
}
这是我想要从第二个发送回主窗口的POCO。
namespace CaliburnMicro.Models
{
class EventMessage
{
public string Text { get; set; }
}
}
答案 0 :(得分:1)
好的,这是一个关于如何使用AppBotstraper
设置EventAggregator
的小例子。
AppBootstrapper.cs
public class AppBootstrapper : BootstrapperBase
{
private SimpleContainer _container;
public AppBootstrapper()
{
Initialize();
}
protected override void Configure()
{
_container = new SimpleContainer();
_container.Singleton<IWindowManager, WindowManager>();
_container.Singleton<IEventAggregator, EventAggregator>();
_container.PerRequest<ShellViewModel>();
}
protected override object GetInstance(Type service, string key)
{
var instance = _container.GetInstance(service, key);
if (instance != null)
return instance;
throw new InvalidOperationException("Could not locate any instances.");
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return _container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
_container.BuildUp(instance);
}
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
DisplayRootViewFor<ShellViewModel>();
}
}
ShellViewModel.cs
public class ShellViewModel : Screen, IScreen, IHandle<EventMessage>
{
private readonly IEventAggregator _eventAggregator;
public ShellViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.Subscribe(this);
}
public void OpenWindow()
{
WindowManager wm = new WindowManager();
SecondWindowViewModel swm = new SecondWindowViewModel(_eventAggregator);
wm.ShowWindow(swm);
}
public void Handle(EventMessage message)
{
MessageBox.Show(message.Text);
}
}
注意:如果您不了解Caliburn.Micro
中的指挥,我建议您阅读this。当您使用指挥时,您可以使用ViewModel
方法UserControl
内的任何一个孩子ActivateItem
开始。
您的SecondWindowViewModel
保持不变,但EventMessage
班级必须为public class EventMessage
,否则您将收到错误。
答案 1 :(得分:0)
只是想一想,您是否设置了DataContext
,以便您的主窗口知道ViewModel是您数据的来源?