我有一个带Caliburn.Micro的WPF应用程序。主ViewModel是ShellViewModel。它包含一个选项卡控件,每个选项卡包含一个用户控件。我需要从该内部用户控件访问ShellViewModel的属性。
var par =((MyApp.ShellViewModel)((Screen)Parent).MyProperty;
虽然不知道ShellViewModel。你能告诉我怎样才能访问它吗?
感谢。
答案 0 :(得分:2)
var parent = IoC.Get<ShellViewModel>();
我目前无法验证语法,但我认为这是正确的。
答案 1 :(得分:2)
好的,你的评论听起来好像你的shell上有一个组合框需要影响其中一个标签上显示的内容。
要在ViewModel之间进行通信,您始终可以使用属于CM的EventAggregator
并实现可以利用的订阅者模式
e.g。
在shell VM上,您可以创建聚合器的静态实例,也可以创建一个单独的静态类,它将聚合器提供给应用程序
static class AggregatorProvider
{
// The event aggregator
public static EventAggregator Aggregator = new EventAggregator();
}
class ShellViewModel : Conductor<IScreen>
{
// When the combo box selection changes...
public void SelectionChanged(object SomeValue)
{
// Publish an event to all subscribers
AggregatorProvider.Aggregator.Publish(new SelectionChangedMessage(SomeValue));
}
}
您使用标准操作消息或约定处理组合框的SelectionChanged
(我不确定CM默认应用于组合中的约定,因此我将显示明确的绑定我的例子)
<ComboBox x:Name="MyCombo" cal:Message.Attach="[Event SelectionChanged] = [Action SelectionChanged(MyCombo)" />
希望如果应用了正确的约定,您应该将所选项目传递给方法
您的子VM只需要订阅聚合器并实现IHandle,其中T是它应该处理的消息类型
class ChildViewModel : Screen, IHandle<SelectionChangedMessage>
{
public ChildViewModel()
{
// Subscribe to the aggregator so we receive messages from it
AggregatorProvider.Aggregator.Subscribe(this);
}
// When we receive a SelectionChangedMessage...
public void Handle(SelectionChangedMessage message)
{
// Do something with the new selection
}
}
SelectionChangedMessage
可以是:
class SelectionChangedMessage
{
public object NewValue { get; private set; }
public SelectionChangedMessage(object newValue)
{
NewValue = newValue;
}
}
显然上面的内容可能是通用类型,因此您可以强烈输入NewValue
参数 - 然后您发布的消息可以是任何内容,所以它取决于您
值得指出的是,您可以从聚合器中Unsubscribe
,以便您可以控制何时收到通知。聚合器无论如何都使用弱引用,因此您不必过于担心取消订阅,但它确实意味着您可以控制对象何时接收消息(即通过订阅{{1}时停止侦听}并取消订阅OnActivate
)。